NOLOCK提示在SELECT语句中的作用

我想真正的问题是

如果我不关心脏读,在SELECT语句中添加(是否)提示是否会影响以下语句的性能:

  1. 当前的SELECT语句
  2. 针对给定表的其他事务

例子:

Select *
from aTable with (NOLOCK)
358921 次浏览

它会更快,因为它不需要等待锁

1) 是的,带有NOLOCK的选择将比普通选择更快地完成。

2) 是的,带有NOLOCK的select将允许对受影响表的其他查询比普通的select更快地完成。

为什么会这样?

NOLOCK通常(取决于你的DB引擎)意味着给我你的数据,我不关心它是什么状态,当你从它读取时,不要打扰它。它速度更快,资源消耗更少,同时也非常非常危险。

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

你真的没有办法知道数据的状态是什么。

如果你试图获得诸如行计数或其他可接受误差范围的汇总数据,那么NOLOCK是提高这些查询性能并避免它们对数据库性能产生负面影响的好方法。

总是非常谨慎地使用NOLOCK提示,并以可疑的方式对待它返回的任何数据。

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

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

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

SET TRANSACTION ISOLATION LEVEL

Table Hint (Transact-SQL) . sql (Transact-SQL

除了上面所说的,你应该非常清楚,nolock实际上强加了你获取已经提交之前你的选择的行的风险。

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

  • 如果查询一次运行多次,答案是Yes,因为每个事务都不需要等待其他事务完成。但是,如果查询单独运行一次,那么答案是No。

  • < >强是的> < /强。仔细使用WITH(NOLOCK)很可能会提高数据库的整体速度。这意味着其他事务不必等待SELECT语句完成,但另一方面,其他事务将变慢,因为它们现在与一个新事务共享它们的处理时间。

注意在有聚集索引的表的SELECT语句中使用WITH (NOLOCK)

WITH(NOLOCK)经常被用作加速数据库读事务的神奇方法。

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

如果WITH(NOLOCK)应用于具有非聚集索引的表,那么行索引可以由其他事务更改,因为行数据正在流到结果表中。这意味着结果集可能缺少行或多次显示同一行。

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