SQL Server选择计数READ_COMMITTED_SNAPSHOT问题


8

在特定表上执行select count(*)时,似乎出现了很多死锁。我已经更改了所有必需的参数,并将它们设置为仅行锁定。

我还更改了数据库以使用READ_COMMITTED_SNAPSHOT隔离,

但是,似乎使用select count(*),其中column =?在表上触发死锁或表上的锁。

我是否正确地认为select count(*)应该只访问中间行?但是,似乎不是那样,并且我仍然遇到死锁。正确的索引编制可能会有所帮助,

问题是:即使将read_committed_snapshot设置为on,SQL Server 2008 R2也会在选择count(*)期间在表上放置共享锁吗?

谢谢


您是否需要一个精确的计数(根据要求),还是可以近似计数?
乔恩·塞格尔

实际上,我只需要知道是否放置了共享锁。我正在尝试调查死锁问题。谢谢
grassbl8d

我的观点是,如果您可以考虑更改获取计数的方式,那可能就是解决死锁问题的方式。但是,现在我再次阅读了该问题,如果您需要使用一个WHERE子句,那么我正在考虑的方法将无法正常工作。
乔恩·塞格尔

如果where子句与过滤索引匹配,则可以从元数据表中获取表子集的近似计数。
亚伦·伯特兰

Answers:


2

注意READ_COMMITTED_SNAPSHOT:如果将其设置为打开,则可能会导致许多细微的错误。

另外,READ_COMMITTED_SNAPSHOT是默认的隔离级别,可能会被某些内容覆盖。运行DBCC USEROPTIONS以确定您选择运行的实际隔离级别。

在您选择之前,我会明确设置“交易隔离级别快照”。这样,您将确保您的选择永远不会陷入死锁,并且不会破坏任何其他代码,例如READ_COMMITTED_SNAPSHOT可能。


0

快照隔离的锁定不会更改。所发生的变化是,当您更改页面时,这些页面将复制到tempdb数据库中,以便您可以从tempdb数据库而不是从普通数据库中读取它们。(是的,这是正在发生的事情的简化版本。)

您提到您没有适当的索引编制,因此您正在执行聚集索引扫描(如果是堆则进行表扫描)。可能有很多数据要移到tempdb数据库。如果此查询将多次运行,建议将索引添加到表中。

您的查询使用什么隔离级别?


我正在使用read_commited_snapshot隔离级别。我在默认情况下使用read_committed时将其打开。我只是对在选择计数期间是否放置锁感兴趣。谢谢,我已经放置了索引btw
grassbl8d 2013年

是的,锁仍在使用中。您可以查询sys.dm_tran_locks以查看正在获取的锁。在一个窗口中运行查询,并在另一窗口中查询sys.dm_tran_locks,以查看正在使用什么锁。您可能正在升级到表锁,并且需要使用提示来强制页面甚至行级锁定。
mrdenny
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.