With(NoLock) 对查询性能有帮助吗?

Rob*_*tin 7 sql-server-2012 nolock

我们存储过程中的大多数 select 语句都使用它WITH(NOLOCK),我的同事告诉我,他们使用它来提高性能。现在,我知道这个提示有助于锁定,但它真的能提高性能吗?我在某处读到我们不应该使用NOLOCKOLTP 数据库中的提示,但我看到我的工作场所正在做相反的事情。有人可以阐明使用提示时的最佳实践吗NOLOCK

Eri*_*ing 13

未承诺的

NOLOCK 提示是 READ UNCOMMITTED 隔离级别的同义词。在本答案期间,请认为它们是等效的并且可以互换。SQL Server 中实现了“未提交读”,以获取最少的架构锁,以防止对正在查询的表进行更改。

  • 添加或删除索引
  • 添加或删除列
  • 添加或删除约束
  • 一些索引重建和重组命令

使用任一方法仍将采用架构锁,但它们将被允许忽略尚未完成其任务的修改查询(插入、更新、删除、合并)所采用的锁,并且回滚或提交事务

除了那些在事务内部使用独占锁定提示(例如 UPDLOCK)的读取查询之外,所有读取查询都将按照存储引擎选择的不同粒度(行、页等)获取并快速释放锁定。读取查询不会出现锁升级。

区别在于隔离级别在遇到锁定的行、页或对象时的行为方式。

在“已提交读”、“可重复读”和“可序列化”下,读查询将被阻止,直到修改释放其锁。

在读取提交快照隔离和快照隔离下,读取查询将从版本存储中读取锁定行的最后一个已知良好版本。

许多“我的查询通过 NOLOCK 变得更快”的结论(错误地)来自于避免被阻止。在“已提交读”下,在某些情况下,读查询还可能与修改查询发生阻塞和死锁。看:

使用 NOLOCK 作为查询提示或使用未提交的读作为隔离级别将避免这些情况。再说一遍,它们是同一件事。

当然还有一个额外的考虑因素,即指定某些锁定提示的查询可以使用 IAM 扫描来读取更少的页面

坚果

请注意,使用 NOLOCK 的查询和使用 TABLOCK 作为提示的查询在聚集索引扫描中大约有 6 秒的差异。

用法

既然你问了:

  • 如果您关心数据正确性,请不要使用 NOLOCK 作为查询提示或 READ UNCOMMITTED 作为隔离级别。
  • 如果您的客户可能会对不正确的结果感到愤怒,请不要使用 NOLOCK 作为查询提示或 READ UNCOMMITTED 作为隔离级别。
  • 如果您的应用程序或数据使用者可能做出错误的决定,请不要使用 NOLOCK 作为查询提示或 READ UNCOMMITTED 作为隔离级别。

读取未提交隔离级别

坚果

为了避免最烦人的阻塞和死锁情况,并最终返回正确的数据,读提交快照隔离级别或快照隔离级别是您的最佳选择。