SQL Server锁与闩锁等待类型解析
1. 降低LCK_M_I[xx]等待时间
当尝试降低LCK_M_I[xx]等待时间时,应聚焦于那些导致阻塞的查询。LCK_M_I[xx]等待仅在锁定层次结构中较高层级的对象持有不兼容锁时发生,因此值得花时间研究这些锁为何会被置于如此高的层级。锁升级可能会导致这种情况。当SQL Server认为在锁定层次结构中较高层级放置单个锁比在较低层级锁定多个对象更高效时,就会发生锁升级。
例如,对于一个包含超过19,000行的 Person.Address 表,执行 SELECT * 查询时,若对每行加共享锁,将需要至少19,000个行锁,这会消耗大量资源。因此,SQL Server会选择在表级别放置一个共享锁,而非对每一行加锁。
若要减少锁的使用,可以重写查询,例如只选择前x行,而非全量数据。以下是一个示例查询,仅选择前2,000行:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN TRAN;
SELECT TOP 2000 * FROM Person.Address;
--COMMIT
执行此查询并查看 sys.dm_tran_locks 动态管理视图(DMV),会发现SQL Server对每一行(由于聚集索引,这里是每个KEY对象)加锁,而非对整个表加共享锁。这意味着其他事务仍可访问该表进行数据修改,只要不修改已加共享锁的行。
超级会员免费看
订阅专栏 解锁全文
1263

被折叠的 条评论
为什么被折叠?



