在保证不会更改的表上使用 NOLOCK 提示是否完全安全?

J.D*_*.D. 5 performance sql-server optimization hints sql-server-2016 query-performance

  1. 如果我有一个数据保证永远不会更改的表,那么将 NOLOCK 提示添加到针对该表的 SELECT 查询中是否完全安全?
  2. 如果我有一个表,其中某些行将被更新,但我只选择保证不会更改的行,这是否也是使用 NOLOCK 提示的完全安全的方案?

Dav*_*oft 14

如果我有一个数据保证永远不会更改的表,那么将 NOLOCK 提示添加到针对该表的 SELECT 查询中是否完全安全?

在实践中,是的(虽然没有这样记录),但也没用。如果您的数据从未改变,那么使用脏读不会导致任何可观察到的行为或材料性能差异。

如果我有一个表,其中某些行将被更新,但我只选择保证不会更改的行,这是否也是使用 NOLOCK 提示的完全安全的方案?

不。绝对不是。读取目标行的查询计划可能会在没有适当并发控制的情况下读取变化的数据结构。因此,您又希望您的查询不会返回奇怪、不正确的结果或只是失败。

  • 在第一种情况下,如果您不使用 READ COMMITTED SNAPSHOT,您可能会看到行锁定的一些成本。但是在那种情况下使用 TABLOCK 而不是 NOLOCK 会强制查询的单个 S 锁。而“变化的数据结构”可能包括数据页和索引。数据页读取和索引读取之间缺乏协调是 NOLOCK 不良的主要原因。 (2认同)
  • 好点子,但 TABLOCK 再次启用了没有脏读的分配顺序扫描。 (2认同)