【发布时间】:2018-09-10 22:22:20
【问题描述】:
我需要将大量数据(数百万行)从一个表传输到另一个表。到目前为止,我已经尝试过这样做......。
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 小时的连续停机,但我可以承受 4 晚 6 小时的停机。
【问题讨论】:
-
TABLE_A has an AFTER INSERT trigger on it that parses each new record and adds a second record to TABLE_B这似乎足够了。可能触发器实施不当,或者级联到辅助触发器。或者它被推迟。一切顺利! -
运行
explain (analyze, verbose) insert ....,您将看到触发器需要多长时间。
标签: postgresql database-performance