SELECT语句中的NOLOCK提示的影响
我想真正的问题是:
如果我不关心脏读,将添加与(NOLOCK)提示到SELECT语句会影响性能:
- 当前的SELECT语句
- 针对给定表的其他交易
例:
Select * from aTable with (NOLOCK)
1) 是的 ,使用NOLOCK
的select将比正常select更快。
2) 是的 ,使用NOLOCK
的select将允许针对受影响的表的其他查询比正常select更快地完成。
为什么会这样?
NOLOCK
通常(取决于您的数据库引擎)意味着给我您的数据,我不在乎它处于什么状态,并且在您读取数据时不要担心。 这一切都是一次更快,资源更less,而且非常非常危险。
您应该被警告不要从系统中进行更新或执行任何系统重要的操作,或者使用源自NOLOCK
读取的数据来确保绝对正确。 这些数据绝对有可能包含在查询运行过程中被删除的行或者在尚未完成的其他会话中删除的行。 这些数据可能包含部分更新的行。 这些数据可能包含违反外键约束的logging。 这些数据可能会排除已添加到表中但尚未提交的行。
你真的没有办法知道数据的状态是什么。
如果您想要获得像行计数或其他汇总数据那样的错误容限,那么NOLOCK
是提高这些查询性能的好方法,并且避免它们对数据库性能产生负面影响。
请务必谨慎使用NOLOCK
提示,并对可疑返回的数据进行处理。
由于缺less共享锁,NOLOCK使大多数SELECT语句更快。 此外,缺less发行锁意味着作家不会被你的SELECT阻碍。
NOLOCK在function上等同于READ UNCOMMITTED的隔离级别。 主要区别在于,如果您select,您可以在某些表上使用NOLOCK,而不使用其他表。 如果您计划在复杂查询中的所有表上使用NOLOCK,则使用SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED更容易,因为您不必将提示应用于每个表。
以下是关于您所处的所有隔离级别的信息,以及表格提示。
设置事务隔离级别
表提示(Transact-SQL)
除了上面所说的之外,你应该非常清楚,nolock实际上是在你select之前实际上强加了你没有得到的行的风险。
它会更快,因为它不必等待锁
-
当前的SELECT将开始更早,因为它不必等待。
-
其他交易将会放慢,因为他们现在正在分享他们的交易时间。
不要使用它。
NOLOCK经常被用作加速数据库读取的神奇方式,但我尽量避免使用它。
结果集可以包含尚未提交的行,这些行通常稍后会回滚。
错误或结果集可能为空,可能缺less行或多次显示相同的行。
这是因为其他交易是在您读取数据的同时移动数据。
READ COMMITTED会在单个列中多个用户同时更改同一个单元格的情况下增加了一个额外的问题。
还有其他的副作用,导致牺牲了你希望首先获得的提速。
现在你知道,不要再使用它了。