在执行 其他任何操作 之前, 应将PostgreSQL 到当前版本,至少是主版本的最新安全版本。请参阅该项目的准则。
我还想强调一下Kevin提到的涉及该列的 LastError
。通常, 可以回收数据页上的死行,并使UPDATE更快得多- 有效地消除了(大部分)清理工作的需要。
如果您的列 以任何方式 在任何索引 中 使用,则会禁用HOT UPDATE,因为它会破坏索引。如果真是这样,您应该可以通过在删除所有这些索引之前并稍后重新创建它们来大大加快查询 的 速度UPDATE
。
在这种情况下,它将有助于运行多个较小的UPDATE: …… update列不包含在任何索引中(启用HOT更新)。…UPDATE
在 多个 事务中很容易分为多个补丁。…这些修补程序中的行分布在整个表上(物理上,而不是逻辑上)。…没有其他并发事务可以防止死元组被重用。
然后,您将不需要VACCUUM
在多个修补程序之间进行操作,因为HOT更新可以直接重用死元组-仅重用来自 先前 事务的死元组,而不是来自相同或并发事务的元组。您可能想VACUUM
在操作结束时安排一个时间,或者只是让自动真空完成其工作。
对于UPDATE
-不需要的任何其他索引,也可以执行相同操作,然后从您的数字判断,UPDATE
无论如何都不会使用索引。如果要更新表的大部分内容,那么从头开始构建新索引要比对每个已更改的行进行增量更新索引要快得多。
另外,您的更新不太可能破坏任何 。您也可以尝试删除并重新创建它们。这确实会打开一个时隙,在该时隙中不会强制执行参照完整性。如果在此期间违反了完整性,则在UPDATE
尝试重新创建FK时会收到错误消息。如果您在一个 事务中完成所有操作,则并发事务永远都不会看到已删除的FK,但是您要在表上进行写锁定-与删除/重新创建索引或触发器相同)
最后,禁用和启用 ****更新不需要的 。
确保一次完成所有这些操作。也许可以在许多较小的补丁程序中执行此操作,因此它不会阻塞并发操作太长时间。
所以:
BEGIN;
ALTER TABLE tbl DISABLE TRIGGER user; -- disable all self-made triggers
-- DROP indexes (& fk constraints ?)
-- UPDATE ...
-- RECREATE indexes (& fk constraints ?)
ALTER TABLE tbl ENABLE TRIGGER user;
COMMIT;
您不能VACUUM
在事务块内运行。每个文档:
VACUUM
无法在事务块内执行。
您可以将您的操作分成几个大块,然后在两个之间运行:
VACUUM ANALYZE tbl;
如果您不必处理并发事务,则可以(甚至更有效):
ALTER TABLE tbl DISABLE TRIGGER user; -- disable all self-made triggers
-- DROP indexes (& fk constraints ?)
-- Multiple UPDATEs with logical slices of the table
-- each slice in its own transaction.
-- VACUUM ANALYZE tbl; -- optionally in between, or autovacuum kicks in
-- RECREATE indexes (& fk constraints ?)
ALTER TABLE tbl ENABLE TRIGGER user;