Postgresql

Postgres中UPDATE FROM VALUES和多個UPDATE語句的區別

  • July 9, 2022

對於同一操作,這兩種形式之間的批量更新通常哪個更有效?

選項1:

UPDATE table SET a = val.b FROM (VALUES (0,1), (2,3)) AS val(b,id) WHERE table.id = val.id

選項 2:

UPDATE table SET a = 0 WHERE table.id = 1;
UPDATE table SET a = 2 WHERE table.id = 3;

我在文件中找到了這個:

當出現 FROM 子句時,實質上發生的情況是目標表連接到 from_item 列表中提到的表,連接的每個輸出行代表目標表的更新操作。

這是否意味著這兩個選項在引擎蓋下是等效的?

對於選項 1,我想知道 Postgres 是否只會在最後更新一次索引,在所有行都更新之後,或者每行更新一次。前者應該比後者更有效,這將使選項 1 比選項 2 更好。

僅僅將索引維護延遲到最後不太可能提高效率——這需要更改算法,而不僅僅是延遲。同樣的工作仍然要做。對於 GIN 索引,有一個“快速更新”機制,但如果它被打開,那麼它將適用於這兩種情況。如果實現了更多/更好的類似“快速更新”的功能,它們可能會以類似的方式實現——這樣它就可以改善這兩種情況。

使用第一種方法的最大優點是它不需要在每次更新之間刷新 WAL,不需要解析/分析/計劃每次更新,也不需要做 IPC/上下文交換/網路往返每次更新時發送給客戶端。但是客戶端可以通過使用顯式事務、準備好的語句或流水線來改善這些問題。

如果值列表很長,將其放入雜湊表然後讀取所有目標表並用它探測雜湊表可能會更快,而不是使用嵌套索引掃描對值列表進行循環目標表。使用第二種方法,即使速度較慢,它也被有效地強制執行嵌套循環。

引用自:https://dba.stackexchange.com/questions/314215