我从事制作网站和应用程序的业务 不是 关键任务 -> 例如。银行软件、太空飞行、重症监护应用程序等你明白了。

那么,有了如此大量的免责声明,在某些 Sql 语句中使用 NOLOCK 提示是否不好?几年前,一位 Sql 管理员同事建议,如果我对“脏读”感到满意,我应该使用 NOLOCK,这会给我的系统带来更多的性能,因为每次读取都不会锁定表/行/任何东西。

我还被告知,如果我遇到死锁,这是一个很好的解决方案。因此,我开始遵循这个想法几年,直到一位 Sql 大师帮助我处理一些随机代码,并注意到我的 sql 代码中的所有 NOLOCK。我被礼貌地斥责了,他试图向我解释(为什么这不是一件好事),但我有点迷失了。我觉得他解释的本质是“这是解决更严重问题的创可贴”。特别是当您遇到僵局时。因此,解决问题的根源'。

我最近做了一些关于它的谷歌搜索并发现 这个帖子.

那么,请一些sql db大师老师赐教一下吗?

有帮助吗?

解决方案

带有Nolock提示,交易隔离水平 SELECT 声明是 READ UNCOMMITTED. 。这意味着查询可能会看到肮脏且不一致的数据。

通常,这不是一个好主意。即使这种肮脏的读取行为对于您的基于任务的基于Web的应用程序还可以,NOLOCK扫描也可能导致601错误,这将由于缺乏锁定保护而导致数据移动终止查询。

我建议阅读 当快照隔离会有所帮助时,何时受伤 - MSDN建议在大多数情况下使用读取的快照,而不是快照。

其他提示

在处理堆栈溢出之前,我反对 NOLOCK 关于您可能会执行的校长 SELECTNOLOCK 并使用可能已过时或不一致的数据取回结果。一个要考虑的因素是可以同时插入/更新多少个记录,另一个过程可能是从同一表中选择数据。如果发生很多事情,那么除非您使用数据库模式,否则会有很高的僵局。 READ COMMITED SNAPSHOT.

从那以后,我改变了对使用的看法 NOLOCK 见证它如何改善之后 SELECT 性能以及消除大量加载的SQL Server上的僵局。有时候,您可能不在乎您的数据并不是100%投入,即使它们可能过时,您也需要快速退缩。

考虑使用时问自己一个问题 NOLOCK:

我的查询是否包括一张桌子,有很高的数量 INSERT/UPDATE 命令,我是否在乎是否在给定的时刻可能会缺少这些更改的数据?

如果答案是否定的,请使用 NOLOCK 提高性能。


我刚刚进行了快速搜索 NOLOCK 在堆栈溢出的代码库中的关键字并找到了138个实例,因此我们在很多地方使用它。

如果您不在乎肮脏的阅读(即主要阅读情况),那么 NOLOCK 很好。

, ,请注意,大多数锁定问题是由于没有用于查询工作负载的“正确”索引(假设硬件取决于任务)。

宗师的解释是正确的。它通常是解决更严重问题的创可贴解决方案。

编辑: :我绝对不是建议应该使用诺洛克。我想我应该很清楚。 (在我分析还可以的极端情况下,我只会使用它)。例如,不久前,我研究了一些撒上诺洛克(Nolock)的TSQL,以减轻锁定问题。我将它们全部删除,实现了正确的索引,所有的僵局都消失了。

怀疑这是一个“大师”,他在交通高昂方面有任何经验...

当人们查看完全加载的页面时,网站通常是“肮脏”的。考虑从数据库加载的表单,然后保存编辑的数据?人们对肮脏的读物的继续方式是愚蠢的。

也就是说,如果您的选择上有许多层,那么您可能会以危险的冗余进行建设。如果您正在处理金钱或状态方案,那么您不仅需要读/写入交易数据,还需要适当的并发解决方案(大多数“大师”不用理会)。

另一方面,如果您有高级产品搜索网站(即可能不会被缓存并有点密集的东西),并且您曾经构建了一个具有多个并发用户的网站(现象有多少“专家”还没有),将其背后的所有其他过程都弄颈是很奇怪的。

知道它的含义,并在适当时使用它。如今,您的数据库几乎总是是您的主瓶颈,并且使用Nolock聪明可以为您节省数千个基础设施。

编辑: 它不仅是僵局,还可以使其他人等到完成,反之亦然。

在EF4中使用Nolock提示?

没有任何答案是错误的,但是有点令人困惑。

  • 查询单个值/行时 总是 使用Nolock的不良练习 - 您可能永远不想显示不正确的信息,甚至可能对不正确的数据采取任何措施。
  • 显示粗略的统计信息时,Nolock可能非常有用。以这样的例子:锁定锁定是胡说八道 精确的 问题的视图数量或标签的确切问题数。没有人关心您是否错误地陈述了3360个问题,现在标记为“ SQL-Server”,并且由于交易回滚,一秒后3359个问题。

作为专业开发人员,我会说这取决于。但是我绝对遵循盖茨和OMG小马的建议。知道您在做什么,知道何时有帮助以及何时受伤,并且

提示和其他可怜的想法

什么可能使您更深入地了解SQL Server。我通常遵循以下规则:SQL提示是邪恶的,但不幸的是,当我厌倦了强迫SQL Server做事时,我时不时地使用它们。

卢克

当App-Support想要使用SSMS从生产服务器中回答Ad-Hock查询时(这不适合通过报告),我要求他们使用Nolock。这样,“主要”业务就不会受到影响。

我同意有关Nolock提示的一些评论,尤其是那些说“在适当时使用”的人。如果应用程序写得不好,并且使用并发不适当的方式 - 可能会导致锁定升级。由于其性质,高度交易桌也一直被锁定。拥有良好的索引覆盖范围无助于检索数据,而是将隔离级别设置为读取不承认。我还认为,在许多情况下,当变化的性质是可以预见的,在许多情况下,使用诺克提示是安全的。例如 - 在制造过程中,当带有许多测量插入的旅行者的工作经历不同的过程时,您可以安全地执行与Nolock Thint的完成作业的查询,这样避免与其他将升级或独家锁的会话发生碰撞/页。在这种情况下,您访问的数据是静态的,但是它可能位于非常交易的表中,每分钟有数亿条记录和数千个更新/插入物。干杯

我相信使用Nolock几乎永远是不正确的。

如果您正在阅读一行,则正确的索引意味着您不需要Nolock,因为单个行操作很快完成。

如果您正在阅读除临时显示以外的许多行,并且要关心能够重复结果或按照所产生的数字进行防御,那么Nolock是不合适的。

Nolock是“我不在乎此答案是否包含重复的行,被删除的行或从未因回滚而开始插入的行的替代标签”

诺洛克(Nolock)可能发生的错误:

  • 匹配的行完全不会返回。
  • 单行多次返回(包括同一主键的多个实例)
  • 返回不匹配的行。

任何可能导致页面拆分的动作在运行Nolock Select时都会导致这些事情发生。几乎所有操作(甚至删除)都可能导致页面拆分。

因此:如果您“知道”在运行时不会更改该行,请不要使用Nolock,因为索引将允许有效检索。

如果您怀疑在查询运行时行会更改行,并且您关心准确性,请不要使用Nolock。

如果您因僵局而考虑诺洛克,请检查查询计划结构是否意外的桌子扫描,追踪僵局并查看为什么发生。 Nolock周围的写作可能意味着以前陷入僵局的查询可能都会写出错误的答案。

最好的解决方案是:

  • 将数据(使用日志复制)复制到报告数据库。
  • 使用SAN快照并安装DB的一致版本
  • 使用具有更好基本交易隔离水平的数据库

由于MS失去了Oracle的销售,因此创建了快照交易隔离级别。 Oracle使用撤消/重做日志来避免此问题。 Postgres使用MVCC。将来,MS的Heckaton将使用MVCC,但这还距离生产准备好了几年。

Nolock通常被利用为加快数据库读取的一种神奇方法,但我尽力避免使用它。

结果集可以包含尚未犯下的行,后来通常会回滚。

错误或结果集可以是空的,缺少行或多次显示同一行。

这是因为其他交易正在同时阅读数据。

读取的添加了一个附加问题,其中数据在单列中损坏了多个用户同时更改同一单元格。

在现实生活中,您遇到已经编写的系统并向表添加索引,然后大大减慢 14gig 数据表的数据加载速度,有时您被迫在报告和月末处理中使用WITH NOLOCK,以便聚合函数(总和) 、计数等)不进行行、页、表锁定并降低整体性能。很容易说在新系统中永远不要使用WITH NOLOCK并使用索引 - 但是添加索引会严重降低数据加载的性能,然后当我被告知时,好吧,更改代码库以删除索引,然后批量加载然后重新创建索引 - 这如果您正在开发一个新系统,那么一切都很好。但当你已经有了一个系统时就不行了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top