我在SQL server 2017上有一个DB。一个带有外键和级联删除的简单表。这个结构真的很简单。
主tblAS0002具有一个具有字段ID (int)的聚集索引。而且,所有子表tblAS0002_xxx都有一个外键字段IdAddress,引用到tblAS0002中的Id字段。对于此示例,子表几乎是空的:不到20000条记录,每个主记录不超过2条记录,大多数主记录在子表中没有关联的记录。
Als子表在IdAddress ( tblAS0002.Id字段的外键)上有一个索引
主表(tblAS0002)有大约250万条记录。对于这个测试,我选择一个在子表中没有记录的记录。当我现在执行1条删除记录时,执行时间超过60秒。
我执行的语句是一个直接的DELETE FROM tblAS0002 WHERE Id=2218801
请参阅公共链接中下面的执行计划。
查看执行计划,我只能看到一个操作花费超过1分钟,这是对tblAS0002的主键索引的扫描。但是为什么呢?
慢删除会发生什么?我在任何地方都找不到缺少的索引。我怎样才能找到幕后的问题呢?
在这里,为表创建脚本 (尽可能简化)
发布于 2020-01-11 17:54:40
执行计划不错!有一系列级联删除(这反过来触发其他级联删除)。每个删除->假脱机都是另一个级联删除:被删除的行被放入假脱机/temp结构中,假脱机用于从其他表中查找引用行。
eg. delete tblAS0002 -> spool[tblAS0002]
delete history{join}spool[tblAS0002] -> spool[history]
delete history_links{join}spool[history]查看执行计划,我只能看到一个操作花费超过1分钟,这是对tblAS0002的主要关键索引的扫描。但是为什么呢?
这是计划底部的操作。
在tblAS0002中有一个自引用: tblAS0002.IdParent -> references tblAS0002.Id
IdParent没有索引,删除单个Id需要对tblAS0002进行表扫描,以验证not exists==断言:!(左半联接),被删除的id没有被任何IdParent引用。
https://stackoverflow.com/questions/59681393
复制相似问题