SQL 服务器中的 DELETE 操作极慢

DELETE operation in SQL Server extremely slow

我在 SQL 服务器 2017 上有一个数据库。一个简单的 table 带有一些外键和级联删除。结构非常简单。

tblAS0002 有一个带字段 ID (int) 的聚簇索引。此外,所有 child tables tblAS0002_xxx 都有一个外键字段 IdAddress 引用 tblAS0002 中的 Id 字段。此样本的 child table 几乎为空:少于 20000 条记录,每个主记录不超过 2 条记录,大多数主记录在 child tables.

Als child table 在 IdAddress 上有一个索引(tblAS0002.Id 字段的外键)

主 table (tblAS0002) 有大约 250 万条记录。对于此测试,我选择了一条在 child table 中没有记录的记录。当我现在执行删除1条记录时,执行时间在60秒以上。

我执行的语句是直接的DELETE FROM tblAS0002 WHERE Id=2218801

请参阅下面的执行计划 public link。

查看执行计划,只有一个操作耗时1分钟,扫描tblAS0002的主键索引。但是为什么?

缓慢删除会发生什么情况?我在任何地方都看不到缺失的索引。我怎样才能找到幕后的问题?

这里Create Script for the tables(尽量简化)

Paste of the execution plan

不错的执行计划!!! 有一系列级联删除(依次触发其他级联删除)。 每个 delete-->spool 都是另一个级联删除:删除的行被放入 spool/temp 结构中,spool 用于从其他 table 中查找引用行。

eg. delete tblAS0002 -> spool[tblAS0002]
delete history{join}spool[tblAS0002] -> spool[history]
delete history_links{join}spool[history]

Looking into the execution plan, I can see only one operation takeing over 1 minute, and it is a scan of the primary key index of the tblAS0002. But why?

这是计划底部的操作。

tblAS0002 中有一个自引用:tblAS0002.IdParent --> 引用 tblAS0002.Id

IdParent 没有索引,删除单个 Id 需要 table 扫描 tblAS0002 以验证不存在== assert:!(left semi join),删除的 id 不存在被任何 IdParent 引用。