[英]PostgreSQL update performance with a select
“名稱”是一個包含大約一百萬行的表。 我已經嘗試過此請求,但它永遠不會結束。 是否有避免“入”的問題?
update name
set name_val = true
where name_pk in (select max (name_pk)
from name
group by foreign_key_pk);
如果有必要,我不反對使用觸發器。
查詢計划:
"Nested Loop (cost=26073.59..26310.38 rows=200 width=54)"
" -> HashAggregate (cost=26073.59..26075.59 rows=200 width=4)"
" -> HashAggregate (cost=23122.82..24598.20 rows=118031 width=12)"
" -> Seq Scan on name (cost=0.00..19956.21 rows=633321 width=12)"
" -> Index Scan using name_pk on name (cost=0.00..1.16 rows=1 width=54)"
" Index Cond: (public.name.name_pk = (max(public.name.name_pk)))"
2個指標:
CREATE INDEX link_name_foreign_key_pk
ON name
USING btree
(foreign_key_pk);
CREATE UNIQUE INDEX name_pk
ON name
USING btree
(name_pk);
謝謝。
創建一個這樣的多列索引 (非常類似於注釋中已經建議的@a_horse ):
CREATE INDEX name_foo_id ON name (foreign_key_pk, name_pk DESC)
DESC
制作速度僅稍快一點。 Postgres幾乎可以向后掃描索引。 但是使用多列索引可能會比較棘手。
並對UPDATE
使用以下替代語法:
UPDATE name n
SET name_val = TRUE
FROM (
SELECT max(name_pk) AS max_pk
FROM name
GROUP BY foreign_key_pk
) x
WHERE n.name_pk = x.max_pk
AND name_val IS DISTINCT FROM TRUE;
對於大集合, IN
可能是最慢的解決方案。 JOIN
應該更快。
附加的WHERE
子句AND name_val IS DISTINCT FROM TRUE
避免了(昂貴的)空更新。
使用NOT EXISTS
進行的反半NOT EXISTS
也可能是性能最高者的競爭者:
UPDATE name n
SET name_val = TRUE
WHERE NOT EXISTS (
SELECT 1
FROM name
WHERE foreign_key_pk = n.foreign_key_pk
AND name_pk > n.name_pk
)
AND name_val IS DISTINCT FROM TRUE;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.