SQL Server NOLOCK和连接
背景:我有一个性能关键的查询,我想运行,我不在乎脏读。
我的问题是 如果我使用连接,那么我是否也必须指定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)
提示,以确保我没有locking连接的表?
只是你原来的问题,我不会READ UNCOMMITTED
未被READ UNCOMMITTED
论点。
是的,在连接的每个表上都需要WITH(NOLOCK)
。 不,你的查询是不一样的。
试试这个练习。 开始一个事务并在table1和table2中插入一行。 不要提交或回滚事务。 此时,您的第一个查询将成功返回并包含未提交的行; 你的第二个查询将不会返回,因为table2没有WITH(NOLOCK)
提示。
我很确定你需要为查询中的每个JOIN
指定NOLOCK
。 但是我的经验仅限于SQL Server 2005。
当我查看MSDN只是为了确认,我找不到任何明确的。 下面的陈述似乎让我觉得,对于2008年,上面的两个陈述是相同的,尽pipe在2005年情况并非如此:
[SQL Server 2008 R2]
所有锁提示都会传播到查询计划访问的所有表和视图,包括视图中引用的表和视图。 此外,SQL Server执行相应的锁一致性检查。
[SQL Server 2005]
在SQL Server 2005中,所有锁提示都会传播到视图中引用的所有表和视图。 此外,SQL Server执行相应的锁一致性检查。
另外,要注意 – 这适用于2005年和2008年:
如果表未被查询计划访问,表格提示将被忽略。 这可能是由于优化器根本不访问表,或者是因为访问了索引视图而造成的。 在后一种情况下,通过使用
OPTION (EXPAND VIEWS)
查询提示可以防止访问索引视图。
都不是。 您将隔离级别设置为READ UNCOMMITTED
,这总是比给出个别锁提示更好。 或者,更好的是,如果您关心一致性等细节,请使用快照隔离 。