替换另一个表中的行

时间:2016-02-03 22:05:32

标签: sql postgresql

我有两个完全相同的列表。第一个用于生产,Web应用程序(django)从中检索对象以在网页上显示。 我正在使用Python脚本将对象添加到第二个。 脚本完成后,我需要用table-2中的行替换table-1中的所有行。现在我正在使用这样的东西:

TRUNCATE table-1;
INSERT INTO table-1 (columns) SELECT columns FROM table-2;
TRUNCATE table-2;
VACUUM FULL;

问题是它需要花费太长时间并且在完成INSERT后,TRUNCATE table-1网站才无用。什么是最好的方法来解决这个问题?

2 个答案:

答案 0 :(得分:2)

你可以尝试创建一个视图和代码django。当需要在table1和table2之间切换时,只需create or replace view切换到另一个表。

答案 1 :(得分:0)

您根本不需要昂贵的VACUUM FULL。在您的大INSERT之后,没有什么可以清理的。没有死元组,所有索引都处于原始状态。

虽然可以立即更新完全更改的表统计信息,但运行'standalone' procedure是有意义的。

对于小型表DELETE可能比TRUNCATE快,但对于中型到大型表TRUNCATE通常会更快。

在一次交易中完成所有工作。 INSERT在同一事务中的TRUNCATE之后不必写入WAL并且速度更快:

BEGIN;
TRUNCATE table1;
INSERT INTO table1 TABLE table2;
TRUNCATE table2;  -- do you need this?
ANALYZE table1;  -- might be useful 
COMMIT;

详细说明:

如果table1上有任何索引,首先删除它们并在INSERT之后为大表重新创建它们是值得的。

如果您没有依赖对象,您也可以放弃table1并重命名table2,这将更快

这两种方法都需要在表格上使用独占锁定。但是你一直在使用How do I replace a table in postgres?

  

VACUUM FULL将表的全部内容重写为新磁盘   没有额外空间的文件,允许将未使用的空间返回给   操作系统。这种形式要慢得多,需要专属   在处理每个表时锁定它们。

因此可以安全地假设您可以使用独占锁。