假设我有一个有1,000,000行的表,在这个表上运行一个SELECT * FROM TableName大约需要10秒才能返回数据。
如果没有NOLOCK语句(将围绕脏读取的问题放在一边),该查询是否会锁定表10秒,这意味着没有其他进程可以对表进行读写?
因此,在查询实时数据以诊断数据问题时,DBA经常通知我,我应该使用NOLOCK来确保不锁定表,这可能会给用户带来问题。这是真的吗?
发布于 2014-04-25 08:52:06
NOLOCK表提示将导致对所讨论的表不使用共享锁;与READUNCOMMITTED隔离级别相同,但这一次不适用于单个表,而是适用于所涉及的所有内容。所以,答案是“不,它不会锁定桌子”。请注意,即使在重新提交的情况下,可能的模式锁仍将保持。
不请求共享锁,读取操作可能会读取脏数据(更新但尚未提交)和不存在的数据(更新,但回滚),在任何情况下事务不一致,甚至跳过整个页面(在读取操作同时发生分页的情况下)。
指定NOLOCK或READUNCOMMITTED并不是一个好做法。当然,它会更快。确保你意识到了后果。
另外,对UPDATE和DELETE语句中这些提示的支持将在以后的版本中删除,根据docs的说法。
发布于 2014-04-25 08:12:22
查询将在询问所有数据时尝试获取表级锁。因此,是的,它将在查询期间保持,所有其他进程都试图获取表上的独占锁,并将其放在等待队列上。也试图从该表读取的进程不会被阻塞。
在活动系统上执行的任何诊断都应该小心,使用NOLOCK提示将允许您查看数据而不为用户创建任何争用。
编辑:如前所述,更新锁与共享锁兼容。所以不会被读取进程阻塞。
发布于 2014-04-25 08:15:41
但是,即使使用NOLOCK,Server也可以选择重写并获得锁。它被称为QUERY **HINT**是有原因的。避免锁定的可靠方法是在会话开始时使用SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED。
https://stackoverflow.com/questions/23287578
复制相似问题