我有一条delete语句,该语句在多个异步线程中运行,其中有时一个线程与另一个线程死锁。本质上,delete语句使用聚簇索引扫描来选择要删除的记录,从而导致页面级死锁。 将聚集索引扫描更改为索引查找将摆脱死锁。 注意:我正在SQL Server 2012上运行它
当我尝试在开发环境中模拟问题时,我可以根据用于比较的其他表中的数据获取查询以使用聚簇索引查找或扫描。
这是我的桌子。
/* Scenario 1 : that leads to Clustered Index Scan on Table1 */
INSERT INTO #Table2(Col1)
SELECT TOP 5000 Col1 from Table2 ORDER BY NEWID()
DELETE IA FROM Table1 T1
INNER JOIN #Table2 T2 ON T1.Col1 = T2.Col1
-------------------------------------------------------
/* Scenario 2: that leads to Clustered Index Seek on Table1*/
INSERT INTO #Table2(Col1)
SELECT TOP 5000 Col1 from Table2 ORDER BY Col1
DELETE IA FROM Table1 T1
INNER JOIN #Table2 T2 ON T1.Col1 = T2.Col1
-------------------------------------------------------
Delete语句在与#Table2进行比较之后,将其从Table1中删除。 #Table2对数据进行排序后,查询将进行聚簇索引查找。 另一方面,#Table2的数据分散(这就是Prod中的状态),查询用于聚簇索引寻求。
{{1}}
在这里,我不确定为什么#Table2中的数据应该决定是否对Table1使用扫描或查找操作。 以及如何实现在方案1中将“扫描”更改为“寻求”。
答案 0 :(得分:0)
选择扫描或查找操作时,优化程序可能会考虑多个因素(硬件差异,当前可用资源等) 尝试在Table1的Col1上创建非聚集索引,在Table2的Col1上创建聚集或非聚集索引