在没有表级锁的情况下在 postgresql 中添加具有默认值的列

Vov*_*ova 4 postgresql performance alter-table postgresql-performance

有这样的问题 - 超过 2000 万行的表。

当我使用默认值添加新列时 - postgresql 锁定表超过 40 分钟,因此我的应用程序此时停止工作。

所以代替

ALTER TABLE "test" ADD COLUMN "field" boolean DEFAULT True NOT NULL;
Run Code Online (Sandbox Code Playgroud)

我愿意

ALTER TABLE "test" ADD COLUMN "field" boolean NULL;
ALTER TABLE "test" ALTER COLUMN "field" SET DEFAULT true;
Run Code Online (Sandbox Code Playgroud)

之后每个新行默认为 true,所以现在我需要更新 2000 万个当前行。我分批更新它们:

WITH cte AS (
SELECT id as pk
FROM "test"
WHERE  "field" is null
LIMIT  10000
)
UPDATE "test" table_
SET "field" = true
FROM   cte
WHERE  table_.id = cte.pk
Run Code Online (Sandbox Code Playgroud)

之后我做

ALTER TABLE "test" ALTER COLUMN "field" SET NOT NULL;
Run Code Online (Sandbox Code Playgroud)

一切都很好,但是我更新行时的步骤太慢了。你能给我一些关于提高更新速度的建议吗?

目前它在大约 2 分钟内更新 10000。我尝试将大小减小到 1000 - 更好(10000 需要 3.5 分钟)但它仍然很慢。我也尝试在更新之前创建索引,但它并没有给出更好的结果(据我所知,它会给出更好的结果,但是当表的巨大路径将被更新时)。

Mad*_*ist 8

这个问题在 PostgreSQL 11 中得到了解决,遗憾的是目前还没有发布。该版本计划于 2018 年第三季度发布。

这篇博文中有更详细的解释,但简短的版本是在版本 11 中不必重写表来向列添加默认值。因此,添加具有默认值的列应该几乎是即时的。