编辑:已解决,桌子上有一个带循环的触发器(请阅读下面我自己的答案)。
我们有一个简单的删除语句,如下所示:
DELETE FROM tablename WHERE pk = 12345
这只是挂起,没有超时,没有任何东西。
我们查看了执行计划,它包含对相关表的许多查找,以确保没有外键会导致删除,但我们已经验证了这些其他表中没有任何行引用该特定行。
此时没有其他用户连接到数据库。
我们已经针对它运行了 DBCC CHECKDB,它报告了 0 个错误。
查看查询挂起时的结果sp_who
,sp_lock
我注意到我的 spid 有很多 PAG 和 KEY 锁,以及偶尔的 TAB 锁。
该表有 1.777.621 行,是的,pk 是主键,所以它是基于索引的单行删除。执行计划中没有表扫描,虽然我注意到它包含一些说Table Spool (Eager Spool)的东西,但是说 Estimated number of rows 1。这实际上是变相的表扫描吗?它只说它查看主键列。
在表上尝试了 DBCC DBREINDEX 和 UPDATE STATISTICS。两者都在合理的时间内完成。
不幸的是,此特定表上有大量索引。它是我们系统中的核心表,包含大量列和引用,包括传出和传入。确切的数字是 48 个索引 + 主键聚集索引。
我们还应该看什么?
还要注意这个表以前没有这个问题,今天突然出现这个问题。我们还有许多具有相同表设置的数据库(客户数据库的副本),它们的行为与预期一样,只是这个有问题。