2

假设我有一个包含 1,000,000 行的表,并且SELECT * FROM TableName在该表上运行 a 大约需要 10 秒才能返回数据。

如果没有NOLOCK 语句(将问题放在脏读方面),这个查询是否会将表锁定 10 秒,这意味着没有其他进程可以读取或写入表?

DBA 经常通知我,然后在查询实时数据以诊断数据问题时,我应该使用 NOLOCK 来确保我不会锁定可能给用户带来问题的表。这是真的?

4

3 回答 3

2

NOLOCK提示将导致不会为有问题的表获取共享锁;与READUNCOMMITTED隔离级别相同,但这次不适用于单个表,而是适用于所涉及的所有内容。所以,答案是'不,它不会锁定桌子'。请注意,即使 readuncommitted 仍会保留可能的模式锁。

不请求共享锁的读取操作可能会读取脏数据(已更新但尚未提交)和不存在的数据(已更新但回滚),在任何情况下事务上都不一致,甚至可能会跳过整个页面(在页面拆分与读取操作同时发生的情况)。

指定NOLOCK或指定READUNCOMMITTED不是一个好的做法。当然,它会更快。只要确保你知道后果。

此外,根据文档,在未来的版本中将删除对 UPDATE 和 DELETE 语句中这些提示的支持。

于 2014-04-25T08:52:06.423 回答
1

尽管如此NOLOCK,SQL Server 仍然可以选择覆盖并获取锁。它被称为是QUERY **HINT**有原因的。避免锁定的可靠方法是SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED在会话开始时使用。

于 2014-04-25T08:15:41.970 回答
1

当您要求所有数据时,您的查询将尝试获取表级锁。所以是的,它将在查询期间保留,并且所有其他进程试图在该表上获取排他锁并放在等待队列中。也试图从该表中读取的进程不会被阻止。

在实时系统上执行的任何诊断都应小心执行,使用 NOLOCK 提示将允许您查看数据,而不会为用户造成任何争用。

编辑:正如指出的更新锁与共享锁兼容。所以不会被读取进程阻塞。

于 2014-04-25T08:12:22.247 回答