Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql Postgres—将数据从一个表批量传输到另一个表_Postgresql_Database Performance - Fatal编程技术网

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

Postgresql Postgres—将数据从一个表批量传输到另一个表,postgresql,database-performance,Postgresql,Database Performance,我需要将大量数据(数百万行)从一个表传输到另一个表。到目前为止,我已经试过了 INSERT INTO TABLE_A (field1, field2) SELECT field1, field2 FROM TABLE_A_20180807_BCK; 这(最终)对一个包含大约1000万行的表有效(耗时24小时)。问题是,我还有其他几个表需要应用相同的过程,它们都要大得多(最大的是2000万行)。我曾经尝试过一个类似的加载,一个包含1200万行的表,但未能在48小时内完成,所以我不得不取消它 其

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

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

这(最终)对一个包含大约1000万行的表有效(耗时24小时)。问题是,我还有其他几个表需要应用相同的过程,它们都要大得多(最大的是2000万行)。我曾经尝试过一个类似的加载,一个包含1200万行的表,但未能在48小时内完成,所以我不得不取消它

其他可能影响性能的问题包括:1)表A有一个基于自动生成序列的字段;2)表A有一个后插入触发器,用于解析每个新记录并向表B添加第二条记录

许多其他线程建议对表A_20180807_BCK进行pg_转储,然后将数据加载回表A。我不确定pg_转储是否对我有效,因为我只对表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
导出/导入方法可能会更快吗?在我开始另一项工作之前,我希望得到一些指导,这可能需要几天才能完成,甚至可能不会更好!“试试看”这个显而易见的答案其实不是一个选择,我承受不起更多的停机时间

(如果需要任何背景细节,这是后续问题)

更新。。。。 我认为触发器没有任何重大问题。在正常情况下,记录以大约1000/秒的速率(包括触发时间)输入到表_A中。我认为问题可能在于交易的规模,在正常情况下,每次插入100条记录的块中插入记录,上面所示的语句试图在单个交易中添加1000万条记录,我猜这就是问题所在,但我无法知道是否真的是这样,或者是否有合适的解决方法(或者如果我建议的导出/导入方法会更快)

也许我应该在前面强调这一点,每次插入表_A都会触发一个触发器,将记录添加到表_B中。表_B中的数据才是最终目标,因此禁用触发器不是一个选项!整个问题的出现是因为我意外地禁用了触发器几天,对于“如何在现有行上运行触发器”这一问题,首选的解决方案似乎是“删除行并再次添加它们”——有关详细信息,请参阅原始帖子(上面的链接)

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

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

编辑postgresql.conf并将检查点_段设置为32或更多

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

编辑:步骤1a

alter table_a set unlogged;
(对要插入的每个表重复步骤1)

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

第三步

   INSERT INTO TABLE_A (field1, field2) 
   SELECT field1, field2 FROM TABLE_A_20180807_BCK;
(对插入的所有表格重复步骤3)

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

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

步骤5a

 Alter table_a set logged;

表A上有一个AFTER INSERT触发器,它解析每个新记录并向表B添加第二条记录,这似乎足够了。可能触发器实现得不好,或者级联到辅助触发器。或者推迟。什么都行!运行
explain(analyze,verbose)insert…
,您将看到触发器花费了多少时间。假设他们正在处理多个表,正如问题所说:“问题是,我有几个其他表需要应用相同的过程,它们都要大得多(最大的是2000万行)。”
 commit;
 Alter table_a set logged;