任何人都可以提出在 SELECT 语句上发出 NOLOCK 的充分理由吗?
我正在重构一些随处可见的存储过程,据我了解,SELECT 语句上的 NOLOCK 几乎毫无用处。
我已经看到一些不好的信息飞来飞去。选择上的 WITH(NOLOCK) 不是在需要速度的地方使用的性能工具。阅读这篇文章,它转储了 eSamuel 提供的答案,因为这是大多数人的想法,正如您从投票中看到的那样。不知道但会反省他们所听到的内容的人应该如何做。首先学习优化您的数据和查询。NOLOCK 提示只应在您始终处理记录被死锁或 NOLOCK 提供解决方案的其他问题的系统中使用。
我在一家金融机构工作,开发OLTP系统,该系统每分钟处理大量交易并为客户和客户提供实时报告功能。这些人整天都在读取我们的新数据,如果我们不使用 NOLOCK 进行报告查询,那么死锁发生只是时间问题。
在将 NOLOCK 视为 SQL 查询速度的圣杯之前,请尽职调查并阅读信誉良好的专业资源,因为它还有更多功能。
所以SELECT
不会被并发数据修改查询阻塞。
有些人认为这是一个神奇的更快的按钮并自由地应用它。它可能比无用更糟糕,除非您的用例接受读取脏(未提交)数据的可能性,这些数据可能在您读取后回滚(因此从逻辑上不存在)以及某些类型异常的可能性更大。
与读取提交隔离级别相比nolock
,您的扫描丢失数据、读取两次或因数据移动错误而完全失败的可能性更大。
NOLOCK 相当于事务上的 READ-UNCOMMITTED。
简而言之,使用 NOLOCK 可确保您的 SELECT 语句快速,因为它不必等待现有锁或事务完成即可返回查询结果。不利的一面是,您最终可能会拉回“脏”数据——这些数据可能在提交之前但在运行 SELECT 语句之后已经回滚。
如果您从内容很少更改的查找表中读取,NoLocks 尤其有用。
当然,nolock 的问题在于,如果正在更新表,您可能会得到错误的数据。对于不断更新的表,在某些情况下可以正确使用 nolock。例如,您有一张桌子:
UserConfig { id int PRIMARY KEY,is_active_flag 位,allow_x_feature 位,allow_y_feature 位}
如果您正在运行选择查询并按 id 过滤,那么即使此表经常更新,您也希望使用 nolock。