我最近在Postgres实现了手动删除级联。我在这个表上使用了pg_depend和DFS来从对象中获取层次结构,但它没有Postgres自己的实现那么快。那么Postgres如何在内部实现呢?
答案 0 :(得分:1)
PostgreSQL的更新/删除级联实现非常简单。它基本上是for each row ... on delete ... execute procedure ...
触发器,伸出并执行delete from only [othertable] where [foreign_key_col] = OLD.[primary_key_col]
。它有一些技巧,用户级触发器无法使用,但这是它的要点。
有关详细信息,请参阅RI_FKey_cascade_del
中的src/backend/utils/adt/ri_triggers.c
。
当FK关系的外部(引用)方面有索引时性能正常,而当引用方是引用列没有索引的大型表时,性能真的很糟糕。
PostgreSQL(或至少9.6和oler)不够聪明,无法批量删除密钥并执行单个大DELETE FROM
。它无法在tuplestore中累积挂起删除键。它必须立即调度每个删除,或者(如果推迟FK关系)将它累积到触发的队列中,这些触发器仍然是单独触发的。
您应该能够轻松击败级联删除的性能,方法是使用DELETE ... FROM ... USING ...
或DELETE ... WHERE EXISTS (...)
批量删除您将从父表中删除的行。