【问题标题】:The use WITH(NOLOCK) in SQL ServerSQL Server 中 WITH(NOLOCK) 的使用
【发布时间】:2020-04-28 07:31:36
【问题描述】:

我有一个关于在 SQL Server 中使用 WITH (NOLOCK / READPAST) 的问题。

当我在一个或两个表上使用 WITH (NOLOCK / READPAST) 提示,并且我在 JOIN 中有其他表时,我应该对所有表使用该提示,还是只对我知道有此需求的表使用该提示?

【问题讨论】:

  • Table hints 按表应用。 Query hints 按查询申请。 Nolock 是一个表格提示。
  • 你能解释清楚为什么你“需要”NOLOCK吗?这是一个名称不太好的查询提示。它还有一些大多数人似乎没有意识到的主要包袱。 blogs.sentryone.com/aaronbertrand/bad-habits-nolock-everywhere
  • 至于手头的问题。没有人可以明确地告诉您是否应该使用所有表格。我会严重倾向于完全不使用。
  • worst 我建议你只在你遇到死锁的表上使用它,并为(始终)错误的数据做好准备。充其量,根本不使用它并修复潜在的性能问题;索引和统计是很好的起点。
  • 添加NOLOCK(除非您的索引缺失)不会加快读取未更改数据的速度,因为引擎足够聪明,可以仅锁定需要锁定的行。对于您几乎完全根据时间读取的表并且仅按时间顺序插入行的表,将插入/审核日期设置为(非唯一)聚集索引会很有意义。然后NOLOCK 应该几乎没有用处,即使这还不够,首先考虑诸如快照隔离和内存表之类的替代方案也是有意义的。将NOLOCK 视为“我不介意错误的结果”。

标签: sql-server nolock


【解决方案1】:

正如 GSerg 在注释表提示中指出的那样,每个表都使用。

OP 评论说她/他正在使用它来阅读日志。我认为日志表不是“索引丰富”的原因有很多,主要是插入性能。

很少或没有索引查询该日志将是一件痛苦的事情,并且很容易退化为表扫描,在一个被大量更新(通过插入)的表上执行它确实会导致(NOLOCK) 的少数情况之一是有道理的。

在连接中的任何表上使用提示,您不怕脏读或丢失锁定行。

编辑

Jeroen 和 Lamu 让我们对 cme​​ts 有了一些很好的了解。我知道很多时候我们无法改变模式,只能适应并尽力做到最好。但是,如果您可以通过更改表/模式来改进您的日志记录/审计功能,请这样做。

【讨论】:

  • 我同意日志表通常索引并不丰富,但是,日志表通常不会很宽,因此很难让它们“丰富”。存档表通常比源表宽,但例如用户操作日志的宽度可能非常小(可能是 7/8 列;ID、用户、日期时间、操作、记录引用)。在我看来,这些可以很容易地拥有很好的索引选择,因为它们有多“薄”。
  • 这是一个包含 40 多列的表。拥有多个列的想法是避免与其他表连接,创建了可读取的数据,但是该表用于许多不同的查询,创建多个索引对于插入来说太慢并且还会有太多的索引来服务所有查询。
  • 即使这是您拥有的那种数据库,您通常最好只是更改默认事务隔离级别,而不是记住在每个查询中放置提示。
  • 针对这种情况推荐什么隔离级别?
猜你喜欢
  • 2016-03-08
  • 1970-01-01
  • 1970-01-01
  • 2020-10-01
  • 2014-02-02
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多