我试图从另一个表填充postgres表,近2400万条记录。但查询变得太慢,需要9-10个小时。更新操作每秒只更新1-2行。我不明白为什么它慢。
当前基准
- 查询=
INSERT INTO .... SELECT FROM .... ON CONFLICT DO UPDATE
- 源表有
24 Million
条记录 - 目标已经有
indexes
、unique keys
、primary and foreign keys
的560 Millions
记录
查询(示例)
INSERT INTO destination_tbl(col1, col2 .... , col22, false AS processed, null AS updated_at)
SELECT (col1, col2 .... , col22) FROM source_tbl
WHERE processed=false
ON CONFLICT (unique_cols...)
DO UPDATE
SET col1 = EXCLUDED.col1
....
col22 = EXCLUDED.col22
processed = false
updated_at = now()
1条答案
按热度按时间lmyy7pcs1#
您提到的查询性能结果似乎确实取决于您的查询。这是一个简单的插入查询,它使用
INSERT ... ON CONFLICT
,这是UPSERT数据的方法之一。但是,如果您使用ON CONFLICT DO NOTHING
或UPDATE
子句,那么性能会非常重要。一般来说,当
DO NOTHING
子句运行时,不会有任何死元组需要清理,而如果使用UPDATE
子句,则会有一个死元组,清理这些死元组可能需要一定的时间,这肯定包含在总的查询执行时间中。我们知道INSERT ON CONFLICT
总是执行读操作来确定必要的写操作。UPSERT
语句只写不阅读,速度更快。对于具有辅助索引的表,UPSERT
和INSERT ON CONFLICT
之间没有性能差异。试着检查一下上述因素,看看是否可以进行批量加载,或者查询划分是否可以减少执行时间,以及fillfactor值集是否有助于减少时间。