通过在打开 READ_COMMITTED_SNAPSHOT 的 SQL Server 数据库上使用 WITH (NOLOCK) 是不是可以获得任何性能提升?

Posted

技术标签:

【中文标题】通过在打开 READ_COMMITTED_SNAPSHOT 的 SQL Server 数据库上使用 WITH (NOLOCK) 是不是可以获得任何性能提升?【英文标题】:Do I get any performance gain by using WITH (NOLOCK) on SQL Server database where READ_COMMITTED_SNAPSHOT is switched on?通过在打开 READ_COMMITTED_SNAPSHOT 的 SQL Server 数据库上使用 WITH (NOLOCK) 是否可以获得任何性能提升? 【发布时间】:2017-08-29 12:28:35 【问题描述】:

我在 Microsoft SQL Server 2014 上有一个数据库,其中 READ_COMMITTED_SNAPSHOT 属性已打开。我理解这意味着读取不会被写入阻塞,因为读取不会发出共享锁,这是干净的读取。

我的问题是:在这种情况下,在 select 语句中使用 WITH (NOLOCK) 是否可以获得任何性能提升?就我而言,我不介意阅读会很脏。

我试图查找此信息,但只找到了使用WITH (NOLOCK) 和打开READ_COMMITTED_SNAPSHOT 之间的比较。但我已经戴上了。

【问题讨论】:

两个都试试看。理论上应该有改进,因为不需要锁记账。 简短回答:可能,可能不会。正确答案:测试。 READ UNCOMMITTED 在这里获得某些东西的唯一方法是,如果 1) 正在进行大量写入,并且 2) 您的读取需要很长时间。在这种情况下,UNCOMMITTED 将允许更快地清理快照行,因为它们不使用旧版本的行。在实践中,很难从中获得性能提升。 大部分行版本控制开销已经在READ_COMMITTED_SNAPSHOT 数据库选项开启时产生。 NOLOCK 可能会略有改进,因为无法访问版本存储,但我没有测试性能。我避免使用 nolock 以避免行被跳过或重复。 丹提出的观点很重要:NOLOCK(或UNCOMMITTED,同样的事情)不仅会给您带来脏读,它还可以给您带来任何一点都完全错误的结果及时,尤其是在数据库负载较重的情况下。这使得您可以在具有可疑价值的SNAPSHOT 数据库上获得(可能很小)的性能提升。我绝对不建议这样做“因为它不会伤害并且可能更快”,因为它可以伤害并且可能更快。 NOLOCK 不是性能工具。这是一个查询提示,对查询的准确性有重大影响。在某些情况下,它可以提高性能,但这是实际情况的副作用。大多数人认为脏读只是查询中未提交的事务,但是当数据转移时还会发生许多其他事务。除了许多其他“有趣”问题之外,您还可以并且将会丢失和/或重复行。你可以在这里读更多关于它的内容。 blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere 【参考方案1】:

理论上应该有改进,因为尽管查询在任何一种情况下都不会阻塞,但在READ_COMMITTED_SNAPSHOT 的情况下,仍然需要与锁关联的簿记,以便数据库知道何时需要创建/保留/清理快照行/页。

但是,对于所有性能问题,您应该尝试一下,看看在实践中是否存在差异,如果存在,它是否对您的用例很重要。

【讨论】:

...如果它很重要,是否值得你在 NOLOCK 上遇到的麻烦。顺便说一句,好点。【参考方案2】:

谢谢大家的建议。

我们进行了一些测试,似乎使用WITH (NOLOCK) 仍然会在性能上有所不同,即使READ_COMMITTED_SNAPSHOT 已打开。

测试用例是:大量更新事务中的某些表(更新 3M 记录),同时在另一个连接中从同一个表中读取。在这个读取语句中使用或不使用WITH (NOLOCK) 会产生巨大的性能差异(使用WITH (NOLOCK) 更快)。

【讨论】:

【参考方案3】:

但在 Azure DB 中要小心!我们有 NOLOCK(从内部部署的日子开始),发现在某些情况下他们发送了 Azure DB berzerk:即以前运行良好的查询(使用 NOLOCK)在 Azure DB 上运行非常缓慢直到 我们删除了 NOLOCK。这与所有建议和所有文档、所有理论等都背道而驰。但是 Azure DB 是一头奇怪的野兽,理论在实践中仍然经常不成立。

【讨论】:

以上是关于通过在打开 READ_COMMITTED_SNAPSHOT 的 SQL Server 数据库上使用 WITH (NOLOCK) 是不是可以获得任何性能提升?的主要内容,如果未能解决你的问题,请参考以下文章

通过 Selenium 在 Chrome 上打开检查(按 F12)

手机怎么通过IP打开电脑本地的HTML文件

如何通过用户输入打开文件? C++

通过macOS中的Finder打开vscode中的文件夹?

如果已经打开,请通过双击防止重新打开工作簿

通过意图打开邮件应用程序不会打开选择器