一切取决于...
删除所有索引(删除ID上需要删除的索引除外)
,然后重新创建它们(比对索引进行增量更新要快得多)
检查是否有可以安全地暂时删除/禁用的触发器
外键是否引用您的表?可以删除它们吗?暂时删除?
根据您的自动真空设置,可能有助于VACUUM ANALYZE
在操作之前运行。
假设没有对相关表的并发写访问权,或者您可能必须专门锁定表,或者此路由可能根本不适合您。
根据您的设置,《填充数据库》手册相关章节中列出的某些要点也可能有用。
如果删除表的大部分,其余部分放入RAM,最快和最简单的方法是:
SET temp_buffers = '1000MB';
CREATE TEMP TABLE tmp AS
SELECT t.*
FROM tbl t
LEFT JOIN del_list d USING (id)
WHERE d.id IS NULL;
TRUNCATE tbl;
INSERT INTO tbl
SELECT * FROM tmp;
这样,您不必重新创建视图,外键或其他依赖对象。阅读temp_buffers
手册中的设置。只要表适合内存,或者至少适合大多数内存,此方法就会很快。请注意,如果服务器在此操作过程中崩溃,则可能会丢失数据。您可以将所有内容包装到事务中以使其更安全。
ANALYZE
之后运行。或者,VACUUM ANALYZE
如果您没有采用截断路线,或者VACUUM FULL ANALYZE
您希望将其最小化。对于大表,请考虑备选方案CLUSTER
/ pg_repack
:
对于小型表,通常使用简单DELETE
而不是TRUNCATE
更快的方法:
DELETE FROM tbl t
USING del_list d
WHERE t.id = d.id;
阅读手册中的“注释”部分TRUNCATE
。特别是(如Pedro在其评论中也指出的那样):
TRUNCATE
不能在具有来自其他表的外键引用的表上使用,除非所有这些表在同一命令中也被截断。[...]
和:
TRUNCATE
不会ON DELETE
触发表可能存在的任何触发器。