207

我想真正的问题是:

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

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

例子:

Select * 
from aTable with (NOLOCK)
4

5 回答 5

303

1)的,选择 withNOLOCK将比普通选择更快地完成。

2)的,选择 withNOLOCK将允许针对受影响表的其他查询比普通选择更快地完成。

为什么会这样?

NOLOCK通常(取决于您的数据库引擎)意味着给我您的数据,我不在乎它处于什么状态,并且在您读取它时不要打扰它。它同时速度更快,资源消耗更少,而且非常非常危险。

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

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

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

始终NOLOCK非常谨慎地使用提示,并可疑地处理它返回的任何数据。

于 2008-10-16T20:43:38.640 回答
62

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

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

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

设置事务隔离级别

表提示 (Transact-SQL)

于 2008-10-16T21:53:05.477 回答
14

除了上面所说的之外,您应该非常清楚 nolock 实际上会带来您无法获得在选择之前已提交的行的风险。

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

于 2011-09-08T22:08:46.410 回答
7

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

于 2008-10-16T20:32:12.813 回答
2
  • 如果查询一次运行多次,答案是肯定的,因为每个事务不需要等待其他事务完成。但是,如果查询单独运行一次,则答案是否定的。

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

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

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

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

如果将 WITH(NOLOCK) 应用于具有非聚集索引的表,则当行数据流式传输到结果表中时,其他事务可以更改行索引。这意味着结果集可能会丢失行或多次显示同一行。

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

于 2016-02-05T16:00:08.260 回答