我需要更新包含许多行的Postgres表。一种优化方法是,计算临时表中的某些字段,然后使用结果更新主表。
当我的表中有数百万行时,最后一步(主表更新)可能会非常缓慢。这是通过以下方式完成的:
UPDATE mytable
SET myfield=tmp_mytable.myfield,
myfieldtwo=tmp_mytable.myfieldtwo
FROM tmp_mytable
WHERE mytable.mypk = tmp_mytable.mypk;
更新是分批完成的,因此我创建了具有10000行的tmp_mytable,然后一次仅更新10000的mytable。
当行数少于(<500万)时,只需几秒钟。但是,迭代次数超过一千万,则每次迭代需要15到30秒。
据我所知,速度之慢是由于索引更新(由于postgres在每次更新时都会在内部创建新行,因此需要重新编制索引)。但是,为了计算某些“ myfields”,我还需要索引,以使联接有效。
我需要用创建索引
CREATE INDEX CONCURRENTLY on mytable(myfield)
但是CONCURRENTLY对于表演毫无用处。
是否有任何技巧来增强更新,或者避免重新计算索引(我的计算中不需要这些索引)?
编辑:最终更新的说明是
Update on mytable (cost=0.42..61854.23 rows=8265 width=732)
-> Nested Loop (cost=0.42..61854.23 rows=8265 width=732)
-> Seq Scan on tmp_mytable (cost=0.00..517.65 rows=8265 width=270)
-> Index Scan using mytable_pkey on mytable (cost=0.42..7.41 rows=1 width=580)
Index Cond: ((mytable_id)::text = (tmp_scene. mytable_id)::text)