我在表之间有一些关系,这些表都与一个“所有者”表相关。所以只是为了这个例子:
- 具有 PK id 的表所有者
- 带有 PK id 和 FK owner_id 的表 Parent 指的是 Owner.id,上面有一个索引,并且
ON DELETE CASCADE
. - 带有 PK id 和 FK parent_id 的表 Child 引用 Parent.id,上面有一个索引,并且
ON DELETE CASCADE
.
Child 表很大(约 5000 万行),Parent 表有几千行,而 Owner 表非常小(约 10 行)。
还有一些与 Owner 和 Parent 相关的其他表,但它们相对较小(几千个)并且还具有外键索引,并且ON CASCADE DELETE
.
有时,当我删除通过所有删除(大约 1200 万个子行和 1000 个父行)级联的所有者行时,工作速度非常快(几秒钟),但有时需要将近一个小时。
我如何弄清楚是什么原因造成的?我做explain
了 on delete from child where parent_id in (select id from parent where owner_id = 1)
,其中 1 是所有者行之一的 id(我尝试了各种 id 以确保)并且它说它正在使用 Bitmap Heap Scan -> Bitmap Index Scan 和 Index Scan。但是,我不确定我是否在模仿有ON DELETE CASCADE
触发器时实际所做的事情。我怎样才能弄清楚是什么导致了这些巨大的延误?是不是有时 Postgres 更喜欢进行顺序扫描(由于行数)?
插入相同的行只需要 8 分钟(包括应用程序逻辑和几千个事务提交),所以我不明白为什么直接删除需要这么长时间。
我正在使用 Postgres 9.1.6