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

问题描述 投票:2回答:1

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

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中的数据,它是最终目标,因此禁用触发器不是一种选择!这整个问题的出现是因为我偶然禁用了触发器几天,并且“如何在现有行上运行触发器”问题的首选解决方案似乎是“删除行并再次添加它们” - 请参阅原始发布(链接上面)了解详情。

我当前的尝试涉及使用带有WHERE子句的COPY命令将TABLE_A_20180807_BCK的内容拆分为十几个小文件,然后一次重新加载一个。这可能不会给我整体节省时间,但是虽然我无法承受24小时的连续停机时间,但我可以承受6个小时的停机时间4晚。

postgresql database-performance
1个回答
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;
© www.soinside.com 2019 - 2024. All rights reserved.