如果一个人避免READ_COMMITTED_SNAPSHOT和WITH NOLOCK,那么下一步是什么?

时间:2011-06-30 14:49:29

标签: sql-server-2005 tsql transactions indexing

<哇哇 - 关于为什么要避免两种选择的信息太多了。

To NOLOCK or NOT to NOLOCK, that is the question

http://www.jimmcleod.net/blog/index.php/2009/08/27/the-potential-dangers-of-the-read-committed-snapshot-isolation-level/

有人说继续使用read-committed和使用锁定提示。其他人说你通常应该避免锁定提示。

启用read-committed会导致非常意外的行为,我认为系统如何包装基本事务代码的很多典型应用程序。

所以 - 问题仍然存在。在sybase迁移之后,我们在生产系统上看到许多阻塞查询。交易时间对我们来说非常重要 - 有些会阻塞10秒以上 - 到处都是。

如果要避免任何一种技术 - 我想了解一些 internals 这里发生了什么。这个问题总是可以通过更好/更合适的索引来解决,或者查询中的索引切换仍然会导致锁定(例如,更新可以使用一个非聚集索引进行搜索,并使用聚簇索引进行行锁定)

让我们说我们做到以下几点:

从Customer CreatedDate&gt;中选择* '6/30/2011'

CreatedDate有一个索引,但显然不是一个关键。

我们看到这样的情况会导致块(不是死锁 - 但是等待很久)等语句(这只是演示代码以显示类似的场景)

更新客户设置OrderReviewed = 1 CreatedDate在'2011年6月24日'和'7/2/2011之间'

有人说 从Customer中选择* with(nolock)CreatedDate&gt; '6/30/2011'

是否可行 - 但是,由于客户可能被删除,页面拆分等,您可能会遇到各种各样的问题。

我们现在无法转动READ_COMMITTED_SNAPSHOT以应对潜在的应用程序影响。

我们在CreatedDate上有一个索引 - 所以...还能做什么呢?

我正在寻找一些专家建议 - 非常好的技术信息 - 不是像'轮廓分析器'或'看到什么是阻塞',因为我们知道阻止了什么,而不是内部的原因或最好的解决方法。

1 个答案:

答案 0 :(得分:0)

如果您对任何这些问题回答“否”,那么这很可能是您的原因:

  • 每张桌子上都有主键吗?
  • 这些是聚集的,还是有其他聚簇索引?
  • “创建和更新”的“自动”统计信息
  • 您是否有索引/统计维护?

而且,停止使用SELECT *。这样,索引将被忽略,或者您将进行密钥查找(如果有几行,则更有可能)。如果表上没有聚簇索引,您甚至无法获得密钥查找:您只能进行昂贵的表扫描

查看查询计划也可以告诉你。

最后,有missing index DMV查询,它提供了最需要索引的位置。这不会覆盖上面的PK /集群要求