如何在PostgreSQL中一次更新数百或数千行

hmmo2u0o  于 2023-03-29  发布在  PostgreSQL
关注(0)|答案(1)|浏览(532)

我想在Postgres中找到一种方法来一次更新单个表中的多行。典型的查询非常简单:

UPDATE mySchema.myTable SET myColumn = 'Foo' WHERE myColumn = 'Bar';

我面临的问题是,很多时候在一个查询中有超过3万行需要更新,如果有+30000行,执行一次更新需要25-30秒。
此外,这并不总是针对同一个表执行。实际上有数百个不同的表,它们跨越许多不同的列,可能需要进行这种耗时的更新。
我曾尝试在列更新之前创建一个索引,希望这样可以加快更新速度,但效果微乎其微。
顺便说一句,我是在一个java程序中使用jdbcTemplate来做这件事的。我不认为在java中执行这件事与这种情况下的效率有任何关系,因为我曾试图直接在pgAdmin中进行同样的查询,但它同样慢。
我听说在Postgres中有一些方法可以在这样的查询中一次更新数百或多达一千行,但我已经能够在我的研究中找到一种方法来做到这一点。
我将感激任何人谁可能会告诉一个方法,使这更有效率。谢谢。
UPDATE:下面是与上面对应的查询的解释计划:

QUERY PLAN
Update on myTable  (cost=0.00..20558.15 rows=30729 width=1566) (actual time=1466.010..1466.011 rows=0 loops=1)      
Buffers: shared hit=373636
   ->  Seq Scan on myTable  (cost=0.00..20558.15 rows=30729 width=1566) (actual time=7.287..39.930 rows=30729 loops=1)       
       Filter: ((myColumn)::text = 'Bar'::text)
       Rows Removed by Filter: 3
       Buffers: shared hit=20174
Planning Time: 0.074 ms
Trigger for constraint myTable_myColumn_fkey: time=845.070 calls=30729
Trigger myTable_history_trigger: time=14287.692 calls=30729
Trigger myTable_trigger_before_update: time=129.909 calls=30729
Trigger tr_myTable_10_before_i_u: time=240.634 calls=30729

执行时间:16618.486毫秒

mzillmmw

mzillmmw1#

分块进行更新,比如说一次更新10K行,方法是重复执行以下命令:

UPDATE mySchema.myTable SET
myColumn = 'Foo'
WHERE myColumn = 'Bar'
AND id < 10000 + (select min(id) from mySchema.myTable WHERE myColumn = 'Bar')

这将使每次执行的日志大小保持适度,并且不会占用系统资源。

相关问题