NOLOCK提示在SELECT语句中的作用

时间:2008-10-16 20:30:04

标签: sql sql-server locking

我想真正的问题是:

如果我不关心脏读,会将 with(NOLOCK)提示添加到SELECT语句会影响性能:

  1. 当前的SELECT语句
  2. 针对给定表格的其他交易
  3. 示例:

    Select * 
    from aTable with (NOLOCK)
    

5 个答案:

答案 0 :(得分:274)

1)NOLOCK的选择将比正常选择更快完成。

2),使用NOLOCK的选择将允许针对受影响的表的其他查询比正常选择更快地完成。

为什么会这样?

NOLOCK通常(取决于您的数据库引擎)意味着向我提供您的数据,而我并不关心它处于什么状态,并且在您从中读取它时不要打扰它。它一下子变得更快,资源更少,而且非常危险。

应该警告您永远不要对系统进行更新或执行任何关键系统,或者使用源自NOLOCK读取的数据需要绝对正确性。此数据绝对可能包含在查询运行期间删除的行或已在其他尚未最终确定的会话中删除的行。此数据可能包含已部分更新的行。此数据可能包含违反外键约束的记录。此数据可能会排除已添加到表但尚未提交的行。

你真的无法知道数据的状态是什么。

如果您尝试获取行计数或其他可接受某些误差范围的摘要数据,那么NOLOCK是提高这些查询性能并避免它们对数据库产生负面影响的好方法性能

请务必谨慎使用NOLOCK提示,并对可疑的任何数据进行处理。

答案 1 :(得分:59)

由于缺少共享锁,NOLOCK使大多数SELECT语句更快。此外,缺少发行锁意味着编写器不会受到SELECT的阻碍。

NOLOCK在功能上等同于READ UNCOMMITTED的隔离级别。主要区别在于,如果您愿意,可以在某些表上使用NOLOCK而不在其他表上使用NOLOCK。如果计划在复杂查询中的所有表上使用NOLOCK,则使用SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED会更容易,因为您不必将提示应用于每个表。

以下是您可以使用的所有隔离级别的信息,以及表提示。

SET TRANSACTION ISOLATION LEVEL

Table Hint (Transact-SQL)

答案 2 :(得分:13)

除了上面提到的内容之外,你应该非常清楚nolock实际上会冒你获取之前之前提交的行的风险。< / p>

请参阅http://blogs.msdn.com/sqlcat/archive/2007/02/01/previously-committed-rows-might-be-missed-if-nolock-hint-is-used.aspx

答案 3 :(得分:6)

它会更快,因为它不必等待锁

答案 4 :(得分:2)

  • 当前的SELECT将提前开始,因为它不必等待。

  • 其他交易将放慢速度,因为他们现在正在与新交易分享处理时间。

不要使用它。

NOLOCK经常被用作加速数据库读取的神奇方法,但我尽量避免使用它。

结果集可以包含尚未提交的行,这些行通常会在以后回滚。

错误或结果集可以为空,缺少行或多次显示同一行。

这是因为其他交易在您正在阅读的同时移动数据。

READ COMMITTED增加了一个额外的问题,即单个列中的数据被破坏,其中多个用户同时更改同一个单元格。

还有其他副作用,导致牺牲你希望首先获得的速度增加。

现在你知道了,再也不用了。