我有两个完全相同的列表。第一个用于生产,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网站才无用。什么是最好的方法来解决这个问题?
答案 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
将表的全部内容重写为新磁盘 没有额外空间的文件,允许将未使用的空间返回给 操作系统。这种形式要慢得多,需要专属 在处理每个表时锁定它们。
因此可以安全地假设您可以使用独占锁。