【问题标题】:PostgreSQL update performance with a select使用 select 更新 PostgreSQL 性能
【发布时间】:2013-06-10 15:00:00
【问题描述】:

“名称”是一个包含大约 100 万行的表。 我已经尝试过这个请求,但它永远不会结束。是否有避免“入”的问题?

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);

谢谢。

【问题讨论】:

  • 执行计划说了什么?表上定义了哪些索引?
  • 我已经编辑了我的原始帖子。
  • 对于注释,name_pk 代表什么,查询可以这样重写吗? postgres.cz/wiki/…
  • 尝试在(foreign_key_pk, name_pk) 上建立索引,尤其是在 Postgres 9.2 中,这可能会有所帮助。
  • 请记住始终包含 表定义 和您的 Postgres 版本,以解决此类问题。对于初学者来说,看看NOT NULL 约束会有所帮助......

标签: performance postgresql select sql-update


【解决方案1】:

像这样创建multi-column index(很像评论中的@a_horse already suggested):

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 的反半联接也可能是性能王冠的竞争者:

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;

【讨论】:

  • 干得好,效果很好!有关信息,第二个请求要快 20%。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-29
  • 2011-06-08
  • 1970-01-01
相关资源
最近更新 更多