在SELECT语句中使用NOLOCK提示的影响

15 浏览
0 Comments

在SELECT语句中使用NOLOCK提示的影响

我想真正的问题是:

如果我不关心脏读,那么在SELECT语句中添加with (NOLOCK)提示会影响以下方面的性能吗:

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

示例:

Select * 
from aTable with (NOLOCK)

0
0 Comments

NOLOCK提示在SELECT语句中的影响

是的,使用NOLOCK提示的SELECT语句比普通SELECT语句执行得更快。

是的,使用NOLOCK提示的SELECT语句允许对受影响表的其他查询比普通SELECT语句执行得更快。

为什么会这样呢?

NOLOCK通常(取决于数据库引擎)意味着给我你的数据,我不关心数据的状态,并且在读取数据时不要停止它。这样做既更快,占用的资源更少,但也非常非常危险。

警告:永远不要使用NOLOCK读取数据执行更新操作或执行任何对系统至关重要、或绝对需要正确性的操作。这些数据可能包含在查询过程中被删除的行,或者在其他会话中被删除但尚未最终确定的行。这些数据可能包含部分更新的行。这些数据可能包含违反外键约束的记录。这些数据可能不包含已添加到表中但尚未提交的行。

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

如果你想获取行数或其他可以接受一定误差的汇总数据,那么使用NOLOCK提示可以提高这些查询的性能,并避免对数据库性能产生负面影响。

始终要非常小心地使用NOLOCK提示,并对其返回的数据持怀疑态度。

谢谢。这是我一直以来的假设,但是我的同事对此提出了质疑,我最初的研究让我对自己产生了怀疑。SQL Server 2005的文档说,对于所有SELECT语句,默认的锁定方案都是使用NOLOCK!我猜测在2005年的情况下,我的提示将是多余的并且没有任何影响。我们现在正在运行2000版(感谢我们的供应商),文档中没有类似的说明。

你的朋友需要阅读文档。表提示(Transact-SQL)msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx

顺便说一下,如果这是真的,那将是绝对的混乱。

第1点和第2点需要限制在1)"...当插入/更新/删除操作在表上挂起时。"和2)"...将允许插入/更新/删除查询..."。个人偏好,我会将"更快"的实例改为"更早",因为差异在于等待另一个进程完成。

0
0 Comments

使用NOLOCK提示可能导致您在选择之前没有获取到已提交的行。这种情况的出现原因是NOLOCK提示会导致读取未提交的数据,因此可能会错过已提交的行。如果想要解决这个问题,可以考虑使用其他的事务隔离级别,如READ COMMITTED或REPEATABLE READ,或者使用其他的查询提示,如READPAST提示。

0
0 Comments

NOLOCK提示在SELECT语句中的效果是使查询变得更快,因为没有共享锁。此外,没有锁的发放意味着写入操作不会被SELECT语句阻碍。

NOLOCK提示在功能上等同于读取未提交的隔离级别(READ UNCOMMITTED)。主要区别在于,如果选择,可以在某些表上使用NOLOCK提示,而在其他表上不使用。如果计划在复杂查询中的所有表上使用NOLOCK提示,则使用SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED更简单,因为不需要将提示应用于每个表。

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

SET TRANSACTION ISOLATION LEVEL

Table Hint (Transact-SQL)

我同意,但并不完全同意;重要的是要指出,NOLOCK / READ UNCOMMITTED提示并不能真正提高查询速度,而是因为它不需要等待之前的查询完成,所以看起来更快。因此,查询似乎更快,而不是实际更快(我认为)。

好吧,这样就不需要从锁管理器请求锁,这样即使没有其他查询在等待,也会有一定的成本和内存开销。

我和我的同事讨论过这个问题。据我了解,使用WITH(NOLOCK)提示的查询仍然需要获取一个模式共享锁。

是的,但不是页面或范围的成千上万个共享锁。一个模式锁只是一个锁,不是成千上万个锁。如果我们想要一丝不苟,我们可以继续争论这个问题,但是是的,锁的开销很小。节省是显著的。在这个链接上进行计算:

0