代码之家  ›  专栏  ›  技术社区  ›  DanP

SQL Server无锁定和联接

  •  133
  • DanP  · 技术社区  · 14 年前

    背景:我有一个性能关键的查询,我想运行,我不关心脏读。

    我的问题是,如果我使用连接,是否也必须在这些连接上指定nolock提示?

    例如;是:

    SELECT * FROM table1 a WITH (NOLOCK)
    INNER JOIN table2 b WITH (NOLOCK) ON a.ID = b.ID
    

    相当于:

    SELECT * FROM table1 a WITH (NOLOCK)
    INNER JOIN table2 b ON a.ID = b.ID
    

    或者我需要详细说明 (NOLOCK) 关于连接的提示以确保我没有锁定连接的表?

    3 回复  |  直到 7 年前
        1
  •  139
  •   codeConcussion    14 年前

    我不会说 READ UNCOMMITTED 争论,只是你最初的问题。

    是的,你需要 WITH(NOLOCK) 在联接的每个表上。不,您的查询不同。

    试试这个练习。开始一个事务,并在表1和表2中插入一行。不要提交或回滚事务。此时,第一个查询将成功返回并包含未提交的行;第二个查询将不会返回,因为Table2没有 有(诺洛克) 提示一下。

        2
  •  16
  •   David Ferenczy Rogožan Hugo L.M    8 年前

    我很确定你需要指定 NOLOCK 为每个 JOIN 在查询中。但我的经验仅限于SQL Server 2005。

    当我查找msdn只是为了确认时,我找不到任何确切的信息。下面的陈述确实让我觉得,2008年,你上面的两个陈述是等效的,但2005年并非如此:

    [SQL Server 2008 R2]

    所有锁提示都将传播到 查询计划访问 ,包括视图中引用的表和视图。此外,SQL Server还执行相应的锁一致性检查。

    [SQL Server 2005]

    在SQLServer2005中,所有锁提示都将传播到视图中引用的所有表和视图。此外,SQL Server还执行相应的锁一致性检查。

    此外,请注意-这适用于2005年和2008年:

    如果查询计划不访问表,则忽略表提示。这可能是由于优化器根本不选择访问表,或者是因为访问了索引视图。在后一种情况下,可以通过使用 OPTION (EXPAND VIEWS) 查询提示。

        3
  •  9
  •   Remus Rusanu    14 年前

    两者都没有。您将隔离级别设置为 READ UNCOMMITTED 这总比给出单独的锁提示要好。或者,更好的是,如果你关心像 consistency 使用 snapshot isolation .