在 PostgreSQL 中更新一个非常大的表而不加锁

Das*_*Boy 1 postgresql large-data sql-update

我有一个非常大的表,有 100M 行,我想在其中更新一列的值,该值基于另一列。下面给出了显示我想要执行的操作的示例查询:

UPDATE mytable SET col2 = 'ABCD'
WHERE col1 is not null
Run Code Online (Sandbox Code Playgroud)

这是具有多个从属的实时环境中的主数据库,我想在不锁定表或影响实时环境性能的情况下更新它。最有效的方法是什么?我正在考虑制作一个程序,使用 limit 之类的方法批量更新 1000 或 10000 行的行,但不太确定如何做到这一点,因为我不太熟悉 Postgres 及其陷阱。哦,两列都没有任何索引,但表有其他列有。

我希望有一个示例程序代码。

谢谢。

Lau*_*lbe 7

没有锁定就没有更新,但是您可以努力保持行锁少而短。

您可以简单地批量运行:

UPDATE mytable
SET col2 = 'ABCD'
FROM (SELECT id
      FROM mytable
      WHERE col1 IS NOT NULL
        AND col2 IS DISTINCT FROM 'ABCD'
      LIMIT 10000) AS part
WHERE mytable.id = part.id;
Run Code Online (Sandbox Code Playgroud)

只要不断重复该语句,直到修改的行数少于 10000 行,就完成了。

请注意,批量更新不会锁定表,但它们当然会锁定更新的行,并且更新的行越多,事务的时间就越长,死锁的风险就越大。

为了提高性能,像这样的索引会有所帮助:

CREATE INDEX ON mytable (col2) WHERE col1 IS NOT NULL;
Run Code Online (Sandbox Code Playgroud)