Postgres-将数据从一个表批量传输到另一个表

时间:2018-09-10 22:22:21

标签: postgresql database-performance

我需要将大量数据(几百万行)从一个表转移到另一个表。到目前为止,我已经尝试过这样做。...

INSERT INTO TABLE_A (field1, field2) 
SELECT field1, field2 FROM TABLE_A_20180807_BCK;

此方法(最终)适用于其中包含约1000万行的表(耗时24小时)。问题是我还有其他几个需要应用相同流程的表,它们都很大(最大的是2000万行)。我曾尝试过对具有1200万行的表进行类似的加载,但该表未能在48小时内完成,因此我不得不取消它。

其他可能影响性能的问题是:1)TABLE_A具有基于自动生成的序列的字段,2)TABLE_A上具有AFTER INSERT触发器,该触发器可解析每个新记录并将第二条记录添加到TABLE_B

许多其他线程建议对TABLE_A_20180807_BCK进行pg_dump,然后将数据加载回TABLE_A。我不确定pg_dump是否真的适合我,因为我只对TABLE_A中的几个字段感兴趣,而不是全部。

相反,我想知道以下问题……。

导出到CSV文件…..

COPY TABLE_A_20180807_BCK (field1,field2) to 'd:\tmp\dump\table_a.dump' DELIMITER ',' CSV;

重新导入所需的表格...。

COPY TABLE_A(field1,field2) FROM 'd:\tmp\dump\table_a.dump' DELIMITER ',' CSV

导出/导入方法可能会更快吗?在我开始另一项可能需要几天才能完成的工作之前,可能需要一些指导,甚至可能做不到更好的工作! “试一试”的明显答案并不是一个选择,我无法承受更多的停机时间!

(如果需要任何背景信息,这是this的后续问题)

更新...。 我认为触发器没有任何重大问题。在正常情况下,记录以大约1000 /秒(包括触发时间)的速度输入到TABLE_A中。我认为问题很可能是事务的大小,在通常情况下,每个INSERT将记录插入100条记录的块中,上面显示的语句试图在单个事务中添加1000万条记录,我想这是问题,但我无法知道它是否确实存在,或者是否有适当的解决方法(或者我提出的导出/导入方法是否会更快)

也许我早些时候应该强调一下,每次插入TABLE_A都会触发一个触发器,该触发器将记录添加到TABLE_B中。最终目标是TABLE_B中的数据,因此禁用触发器不是一种选择!之所以出现整个问题,是因为我无意中禁用了触发器几天,而“如何在现有行上运行触发器”这个问题的首选解决方案似乎是“删除行并再次添加它们”-请参见原始发布(上面的链接)以获取详细信息。

我当前的尝试涉及将COPY命令与WHERE子句一起使用,以将TABLE_A_20180807_BCK的内容拆分为十二个小文件,然后一次重新加载一个。这可能无法为我节省任何时间,但是尽管我无法承受24小时的连续停机时间,但我可以承受6个小时的4个小时的停机时间。

1 个答案:

答案 0 :(得分:1)

准备(如果您有权访问并可以重新启动服务器),请将checkpoint_segments设置为32或更高。这将减少此操作期间检查点的频率和数量。完成后,您可以撤消它。此步骤并非完全必要,但应大大加快写入速度。

编辑postgresql.conf并将checkpoint_segments设置为32或更多

步骤1:删除/删除表A上的所有索引和触发器。

编辑:步骤1a

alter table_a set unlogged;

(对要插入的每个表重复步骤1)

第2步。(如果您一次只做一张桌子,则不需要)

 begin transaction;

第3步。

   INSERT INTO TABLE_A (field1, field2) 
   SELECT field1, field2 FROM TABLE_A_20180807_BCK;

(对所有要插入的表重复步骤3)

步骤4。(如果您一次只做一张桌子,则不需要)

 commit;

第5步在所有表上重新启用索引和触发器。

第5a步。

 Alter table_a set logged;