Kar*_*san 3 postgresql trigger foreign-key ddl postgresql-performance
我正在从 PostgreSQL 表中删除 750k 行中的 130k。
第一次,花了8个小时才完成删除查询。
第二次,我向表中添加了一个索引,并重建了该索引。现在用了3个小时完成删除查询
第三次,我添加了以下行:
alter table contact disable trigger ALL;
delete from contact where ....;
alter table contact enable trigger ALL;
Run Code Online (Sandbox Code Playgroud)
删除行花了不到一秒钟的时间。即使没有与当前和外键表关联的触发器。
即使没有与表关联的触发器,这种快速查询性能的原因可能是什么?数据库级别还有其他类型的触发器吗?
此命令的副作用是您对表进行了排他锁:
ALTER TABLE DISABLE trigger ALL;
Run Code Online (Sandbox Code Playgroud)
此命令获取
SHARE ROW EXCLUSIVE锁。
[...] 这种模式可以保护表免受并发数据更改的影响,并且是自排的,因此一次只有一个会话可以保留它。
这可以防止在大期间与并发事务发生锁定争用DELETE- 这可以解释您自己报告的不合理的长时间。
该效果独立于表上实际存在的任何触发器。但事实上,你确实有触发器。您提到了外键表,并且 FK 约束是在内部使用特殊触发器实现的。看:
由于您指定ALL(而不是USER),这些都包括在内。
又是说明书:
可以禁用或启用按名称指定的单个触发器,或表上的所有触发器,或仅用户触发器(此选项不包括内部生成的约束触发器,例如用于实现外键约束或可延迟唯一性和排除约束的触发器)。
大胆强调我的。
当然,禁用 FK 检查可以节省时间。(特别是如果这会在并发负载下触发一系列附加触发器......)但它也可能破坏引用完整性和功能,如CASCADE选项。所以这是为超级用户保留的,并且手册警告不要这样做。请务必阅读。
不能说这两种效应中哪一种贡献更大。