使用Read Uncommitted时锁定

时间:2014-04-25 02:33:39

标签: sql-server deadlock

我有一个查询需要一段时间才能运行,所以它的隔离级别设置为Read Uncommitted,数据可能很脏,因为它只用于快速概览系统。

在美好的一天(早上的第一件事)查询需要大约3-15秒才能运行。 (日期排序会降低它的速度,它的瞬间没有排序)

但是,随着一天的开始,它需要花费很长时间才能运行,它最终会采用>运行2分钟。

我注意到的是查询在执行时似乎获得了很多OBJECT / PAGE锁。

我不明白为什么它在设置为Read Uncommitted时获取锁定。


查询使用的索引之一设置为使用行/页锁定。

我的问:

enter image description here

设置为使用行/页锁定的索引是否会导致数据在被访问时被锁定,即使查询是未提交读取的?

1 个答案:

答案 0 :(得分:0)

READ UNCOMMITTED隔离级别只会改变读者的行为。在READ COMMITTED和更高的隔离级别中,当任务尝试从行读取时,它会向锁定管理器请求共享锁定。只有当其他会话中没有现有的独占锁时,才会尊重此请求,否则必须等待它。

READ UNCOMMITTED中,读者不会请求共享锁,因此无法等待释放可能的独占锁。

但是,无论使用何种隔离级别,更新时的锁定行为都是相同的。与{em>悲观隔离级别中的任何其他悲观隔离级别一样,仍在READ UNCOMMITTED中进行独占锁定(并且在事务结束时保持不变)。

查询完成所需时间的增加可归因于此,或某些资源争用,很可能与内存相关。简而言之,您的查询与其他同时运行的查询竞争数据缓存。

在一天中的不同时间记下page life expectancy个计数器:

SELECT @@SERVERNAME AS [Server Name], [object_name], instance_name, cntr_value AS [Page Life Expectancy]
FROM sys.dm_os_performance_counters WITH (NOLOCK)
WHERE [object_name] LIKE N'%Buffer Node%' -- Handles named instances
AND counter_name = N'Page life expectancy' OPTION (RECOMPILE);

另外,要查看哪些数据占用的空间最多,请使用以下查询:

SELECT OBJECT_NAME(p.[object_id]) AS [Object Name], p.index_id, 
CAST(COUNT(*)/128.0 AS DECIMAL(10, 2)) AS [Buffer size(MB)],  
COUNT(*) AS [BufferCount], p.Rows AS [Row Count],
p.data_compression_desc AS [Compression Type]
FROM sys.allocation_units AS a WITH (NOLOCK)
INNER JOIN sys.dm_os_buffer_descriptors AS b WITH (NOLOCK)
ON a.allocation_unit_id = b.allocation_unit_id
INNER JOIN sys.partitions AS p WITH (NOLOCK)
ON a.container_id = p.hobt_id
WHERE b.database_id = CONVERT(int,DB_ID())
AND p.[object_id] > 100
GROUP BY p.[object_id], p.index_id, p.data_compression_desc, p.[Rows]
ORDER BY [BufferCount] DESC OPTION (RECOMPILE);

[此处和其他诊断查询可在此处找到:http://sqlserverperformance.wordpress.com/]