我有巨大的postgres表(10GB数据-1.6亿条记录)。该表是静态的,并且没有对其执行任何写操作。我想复制它,执行写操作,重新索引它,然后通过一次快速事务删除旧的并将其重命名为原始名称。

复制这种大表的最快方法是什么?

#1 楼

通常,复制表的最快方法是:

CREATE TABLE table2 AS SELECT * FROM table1;


并行INSERT可能更快,但只有在磁盘子系统非常快的情况下(当数据在许多驱动器上交错时) )。否则,它将变慢。

修改完table2后,可以使用以下新名称:

BEGIN;
DROP TABLE table1;
ALTER TABLE table2 RENAME TO table1;
COMMIT;


DROP TABLE该命令需要一个排他锁,这会以您可能希望的方式影响并发阅读器:




DROP将等待其他事务对表的所有未决读取完成。
与此同时,任何尝试读取该表的新事务都会将其置于等待状态,然后失败,因为原始table1不再存在。该错误看起来像是“无法打开与OID oid的关系”

为避免第二个问题,您可以将table1重命名为old_table1而不是将其删除,然后仅在事务之外将其删除,这些读者完成后。因此,上面的序列将变为:

BEGIN;
ALTER TABLE table1 RENAME TO old_table1;
ALTER TABLE table2 RENAME TO table1;
COMMIT;
...
DROP TABLE old_table1;


评论


谢啦。这正是我正在寻找的解释。再次感谢!

–米洛万·佐格维奇(Milovan Zogovic)
2013年12月27日下午14:12

如果在table2上定义了索引,则在重命名表后它们仍然可以工作吗?

– BamaPookie
16-10-19在16:25

@BamaPookie可以检查出完整的架构,包括索引,约束和默认值wiki.postgresql.org/wiki/Clone_schema

–提莫西·沃格尔(Timothy Vogel)
16年11月2日,19:39



#2 楼

您可以使用开放源代码重复数据删除器-使用JDBC:https://github.com/bmiller1009/deduper

评论


Afaik的问题是关于重复,而不是重复。

–peterh-恢复莫妮卡
20-2-26在3:57