Postgres 11 或更高版本
从 Postgres 11 开始,只有 volatile 默认值仍然需要重写表。手册:
添加具有volatile DEFAULT
的列或更改现有列的类型将需要重写整个表及其索引。
大胆强调我的。false
是不可变的。所以只需添加带有DEFAULT false
. 超级快,完成工作:
ALTER TABLE tbl ADD column delta boolean DEFAULT false;
Postgres 10 或更高版本,或用于 volatileDEFAULT
添加新列而不 DEFAULT
强制或DEFAULT NULL
通常不会强制表重写,并且非常便宜。仅向其写入实际值会创建新行。但是,引用手册:
添加带有DEFAULT
子句的列或更改现有列的类型将需要重写整个表及其索引。
UPDATE
在 PostgreSQL 中写入行的新版本。您的问题并未提供所有信息,但这可能意味着要编写数百万行新行。
在执行UPDATE
就地操作时,如果表的主要部分受到影响并且您可以自由地以独占方式锁定表,请在执行批量操作之前删除所有索引并在UPDATE
之后重新创建它们。这种方式更快。手册中的相关建议。
如果您的数据模型和可用磁盘空间允许,则CREATE
在后台创建一个新表,然后在一个事务中:DROP
旧表和RENAME
新表。有关的:
在后台创建新表时:一次将所有更改应用于同一行。重复更新会创建新的行版本并留下死元组。
如果由于限制而无法删除原始表,另一种快速方法是构建一个临时表,TRUNCATE
即原始表并大量INSERT
新行 - 排序,如果这有助于提高性能。一站式交易。像这样的东西:
BEGIN
SET temp_buffers = 1000MB; -- or whatever you can spare temporarily
-- write-lock table here to prevent concurrent writes - if needed
LOCK TABLE tbl IN SHARE MODE;
CREATE TEMP TABLE tmp AS
SELECT *, false AS delta
FROM tbl; -- copy existing rows plus new value
-- ORDER BY ??? -- opportune moment to cluster rows
-- DROP all indexes here
TRUNCATE tbl; -- empty table - truncate is super fast
ALTER TABLE tbl ADD column delta boolean DEFAULT FALSE; -- NOT NULL?
INSERT INTO tbl
TABLE tmp; -- insert back surviving rows.
-- recreate all indexes here
COMMIT;