下面是 https:/stackoverflow.coma5301619310894456。是为Oracle 11g提供的答案,我的问题也是一样。
在生产的oracle数据库中,当一个表包含100万条记录并且是实时的时候,添加一个具有默认值的非空列的最佳方法是什么?如果我们在一条语句中创建列,添加默认值并将其设为非空,是否会产生任何锁?
但对于PostgreSQL来说呢?
此前的回答 基本上回答了你的疑问。
交叉引用 相关PostgreSQL文档 与PostgreSQL源码的 AlterTableGetLockLevel
上述答案中提到的,说明 ALTER TABLE ... ADD COLUMN
将永远获得 ACCESS EXCLUSIVE
表锁,阻止任何其他事务在该表的 ADD COLUMN
这个相同的独占锁可以在任何一个 ADD COLUMN
变化;即无论你是否添加了一个。NULL
栏目 DEFAULT
)或有 NOT NULL
含有一个默认值。
然而,正如上面链接的答案中提到的,在一个默认的情况下,添加一个 NULL
栏目,没有 DEFAULT
应该是非常快的,因为这个操作只是更新目录。
与此相反,添加一个带有 DEFAULT
根据链接的答案,PostgreSQL >= 11不需要重写这样的列,所以应该更类似于不需要重写。DEFAULT
的情况。
我需要补充的是,对于PostgreSQL 11及以上的版本来说,在PostgreSQL 11中的 ALTER TABLE
文件 注意,只有在非易失性的情况下,才会避免表的重写。DEFAULT
指定符。
当使用ADD COLUMN添加一列并指定一个非易失性的DEFAULT时,默认值将在声明时进行评估,结果存储在表的元数据中。该值将被用于所有现有行的列。如果没有指定DEFAULT,则使用NULL。在这两种情况下,都不需要重写表。
添加一个具有易失性DEFAULT的列[...]将需要重写整个表和它的索引。[...]对于一个大表来说,表和或索引的重写可能需要大量的时间;并且会暂时需要多达一倍的磁盘空间。