如何在Postgresql中有效地将数百万行从一个表复制到另一个表?


36

我有两个数据库表。其中包含数亿条记录。让我们称之为那个history。另一条是每天计算的,我想将其所有记录复制到history一条中。

我所做的就是跑步:

INSERT INTO history SELECT * FROM daily

它成功完成了一段时间,但随着记录数量的不断增长,它开始变得越来越慢。现在,我大约有200万条记录需要通过一次操作从daily到进行复制,history而完成它花费的时间太长。

是否有另一种更有效的方法将数据从一个表复制到另一个表?

Answers:


10

如果您打算长时间(数月)保留历史记录,建议您查看分区选项-每天或每周可能是一个分区,依此类推。它的确也取决于您的历史记录表的访问模式(您是否运行查询以跨日期访问数据?是否进行了大量汇总等)。查看用于存储汇总/摘要的实例化视图。 http://www.postgresql.org/docs/9.3/static/ddl-partitioning.html http://www.postgresql.org/docs/9.3/static/sql-creatematerializedview.html


感谢您的回答。这似乎是唯一的方法。我需要按月对数据进行分区,从而使重新索引(因为这里的索引再生是个问题)要快得多。
Milovan Zogovic

16

以csv格式转储表

COPY table TO '/tmp/table.csv' DELIMITER ',';

使用COPY命令,该命令对于大量数据效率更高。

COPY table FROM '/tmp/table.csv' DELIMITER ',';

有关更多信息,请访问http://www.postgresql.org/docs/current/static/sql-copy.html查看postgres文档。


1
它仍然运行得非常非常慢...也许它不得不做一些重建巨大索引的事情?表中有1.6亿行history,我们还要追加3百万行。
Milovan Zogovic

2
在您要填充一个空表或添加比现有表多的行中,通常,删除非聚集索引并在传输完成后重新创建它们会更为有效(除非当时正在积极使用该表) )
David Spillett

顺便说一句,这是一次性操作还是您必须定期执行的操作?如果我定期建议您创建一个触发器,那么您不必每次都要经历此苦难。
Fabrizio Mazzoni 2013年

@FabrizioMazzoni-必须每天在特定时间执行一次(一定要及时拍摄快照)。
Milovan Zogovic

@DavidSpillett-的确如此!删除索引品牌导入速度非常快(见我的回答以上),但是,重新创建索引需要几个小时(因为我在数据库160M行)..
米洛Zogovic

13

问题出在索引上。该history表具有1.6亿个索引行。通过运行其中一个,COPY FROM或者INSERT INTO .. SELECT不花大量时间不插入行,而是更新索引。当我禁用索引时,它在10秒内导入了3M行。现在,我需要找到重新索引大表的更快方法。


3
您甚至需要在历史记录表上建立索引吗?
Sherlock

2
使用CONCURRENTLY关键字添加索引
Akvel,2016年

10

您可以使用psql工具,如下所示,我可能会比较有效,

psql -h ${DAILY_HOST_IP} -p ${PG_PORT} ${DB_NAME} ${USER_NAME} -c "copy daily to stdout " | psql -h ${HISTORY_HOST_IP} -p ${PG_PORT} ${DB_NAME} ${USER_NAME}  -c "copy history from stdin"

您也可以编写一个shell脚本。


没有中间文件的绝佳解决方案。我也非常快地在1h20(不包含索引)之间在常规磁盘和网络文件系统之间复制了9.5亿行表。
Le Droid

3

这当然不是您问题的确切答案,但是如果您不需要访问history表,则还可以生成一个SQL转储:

pg_dump -h host -p port -w -U user db > dump.sql

然后,可以使用一种工具git来计算差异并有效地存储差异。

git add dump.sql
git commit -m "temp dump"
git gc --aggressive

这很有用,因为数据库中的大多数部分每天都不会更改。不必每天存储整个副本,而是可以存储两天之间的差额。

您可以使用crontab作业来每天处理转储。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.