我正在使用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;
此致 希瓦。
答案 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来检查查询为何需要这么长时间。
我最近有类似的情况,并添加一个索引解决了这个问题。