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 秒的差异。
既然你问了:
为了避免最烦人的阻塞和死锁情况,并最终返回正确的数据,读提交快照隔离级别或快照隔离级别是您的最佳选择。