请推荐最佳的批量删除选项

时间:2011-11-17 18:07:07

标签: sql postgresql

我正在使用PostgreSQL 8.1.4。我有3个表:一个是核心(table1),另一个是dependents(table2,table3)。我在table1中插入了70000条记录,在其他2个表中插入了相应的相关记录。由于我使用了CASCADE,我可以使用DELETE FROM table1删除相关记录;当我的当前PostgreSQL版本中的记录最小时,​​它工作正常。当我有大量的记录时,它会尝试删除所有记录但是没有任何删除进度的迹象好几个小时!然而,批量导入,只需几分钟。我希望在合理的时间内进行批量删除。我也试过TRUNCATE。比如,TRUNCATE table3,table2,table1;尽管如此,性能没有变化。它只需要更多时间,而且没有完成的迹象!从网上,我有几个选项,比如,删除所有约束,然后重新创建相同的将是好的。但是,当它加载更多数据时,似乎没有查询成功运行'table1'! 请推荐我在几分钟内删除所有记录的最佳解决方案。

CREATE TABLE table1(
        t1_id   SERIAL PRIMARY KEY,
        disp_name       TEXT NOT NULL DEFAULT '',
        last_updated TIMESTAMP NOT NULL DEFAULT current_timestamp,
        UNIQUE(disp_name)
    ) WITHOUT OIDS;

CREATE UNIQUE INDEX disp_name_index on table1(upper(disp_name));

CREATE TABLE table2 (
        t2_id           SERIAL PRIMARY KEY,
        t1_id   INTEGER REFERENCES table1 ON DELETE CASCADE,
        type    TEXT
    ) WITHOUT OIDS;

CREATE TABLE table3 (
        t3_id           SERIAL PRIMARY KEY,
        t1_id   INTEGER REFERENCES table1 ON DELETE CASCADE,
        config_key      TEXT,
        config_value    TEXT
    ) WITHOUT OIDS;

此致 希瓦。

3 个答案:

答案 0 :(得分:2)

您可以在引用父表的子表的列上创建索引:

table2上的

在t1_id列上创建一个索引

表3上的

在t1_id列上创建索引

应该稍微加快速度。

和/或者,不要打扰on delete cascade,制作一个删除存储过程,首先从子表中删除,然后从父表删除,它可能比让postgresql为你做的更快。

答案 1 :(得分:0)

  

在SQL中, TRUNCATE TABLE 语句是数据定义语言   (DDL)操作,用于标记表的扩展区以进行解除分配   (空可重复使用)。此操作的结果很快就会删除所有操作   来自表的数据,通常绕过一些完整性   执行机制。   http://en.wikipedia.org/wiki/Truncate_(SQL

所以截断应该非常快。在您的情况下,看起来您有一个未提交或回滚的事务。在这种情况下,您的删除交易永远不会完成。

要解决此问题,您应该检查数据库中的活动事务。最简单的方法(至少在SQL Server下,它可以工作)是写“ROLLBACK COMMIT;”进入查询窗口并执行它。如果它执行而不抛出错误,则意味着实际上存在活动事务。如果没有剩余活动交易,则会给您一个错误。

答案 2 :(得分:0)

我敢打赌你也错过了数据库中的一些索引。

如果从psql控制台发出delete命令,只需按Ctrl-C - 事务将被中断,psql应该通知您在中断时正在执行哪个查询。

然后使用EXPLAIN来检查查询为何需要这么长时间。

我最近有类似的情况,并添加一个索引解决了这个问题。