Postgresql
Postgres中UPDATE FROM VALUES和多個UPDATE語句的區別
對於同一操作,這兩種形式之間的批量更新通常哪個更有效?
選項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/上下文交換/網路往返每次更新時發送給客戶端。但是客戶端可以通過使用顯式事務、準備好的語句或流水線來改善這些問題。
如果值列表很長,將其放入雜湊表然後讀取所有目標表並用它探測雜湊表可能會更快,而不是使用嵌套索引掃描對值列表進行循環目標表。使用第二種方法,即使速度較慢,它也被有效地強制執行嵌套循環。