簡體   English   中英

PostgreSQL通過選擇來更新性能

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM