具有外键约束的表上非常缓慢的SQL DELETE查询

5

我在SQL的DELETE查询中遇到了一些麻烦。

我的工作数据库是(postgres 9.3),由两个表(父表和子表)组成。

子表通过外键与父表建立了关系。

父表:

CREATE TABLE parent
(
  id bigint NOT NULL,
  ...
  CONSTRAINT parent_pkey PRIMARY KEY (id)
)

子表

CREATE TABLE child
(
  id bigint NOT NULL,
  parent_id bigint,
  ...
  CONSTRAINT child_pkey PRIMARY KEY (id),
  CONSTRAINT fk_adc9xan172ilseglcmi1hi0co FOREIGN KEY (parent_id)
      REFERENCES parent (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

我在两个表中都插入了200,000条没有任何关系的记录(Child.parent_id = NULL)

但是像下面这样的DELETE查询需要超过20分钟的时间。 即使没有WHERE条件。

DELETE FROM Parent;

如果我不添加关系约束,执行时间将在400毫秒内完成。
我错过了什么?
下面是一个可行的解决方案示例。但我不知道这是否是一个好主意。也许有人可以告诉我更好的方法来做到这一点。
BEGIN WORK;
ALTER TABLE Parent DISABLE TRIGGER ALL;
DELETE FROM Parent;
ALTER TABLE Parent ENABLE TRIGGER ALL;
COMMIT WORK;

2
好吧...你的“触发器”在干什么? - Siyual
我认为他们是因为'NO ACTION'语句而什么都没做。 - Simon Schüpbach
我自己没有添加任何触发器,但是数据库会根据约束自动添加一些触发器,我想是这样。 - Simon Schüpbach
1个回答

4
当您从Parent删除时,需要通过parent_id查询Child表,以确保没有子行引用即将要删除的父行。
为确保子查询运行快速,您需要在Child表中的parent_id列上建立索引。

我必须注意第一个要点,但第二个真的很有帮助。 - Simon Schüpbach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接