【问题标题】:Improve performance of UPDATE WHERE sql query提高 UPDATE WHERE sql 查询的性能
【发布时间】:2018-11-14 12:06:59
【问题描述】:

我有一个非常简单的查询

UPDATE TableA
SET date_type = TableB.date_type
FROM TableB
WHERE TableB.int_type = TableA.int_type

我的指数是: TableA(int_type), TableB(int_type, date_type)

EXPLAIN 结果:

Update on TableA  (cost=2788789.320..34222368.900 rows=82594592 width=261)
  ->  Hash Join  (cost=2788789.320..34222368.900 rows=82594592 width=261)
          Hash Cond: (TableA.int_type = TableB.int_type)
        ->  Seq Scan on tableA  (cost=0.000..12610586.960 rows=101433296 width=247)
        ->  Hash  (cost=1272403.920..1272403.920 rows=82594592 width=18)
              ->  Seq Scan on TableB  (cost=0.000..1272403.920 rows=82594592 width=18)

查询已超过 3 小时。

可以做些什么来让它运行得更快?从EXPLAIN 结果中可以看出,没有使用索引。我应该选择其他索引/进行任何其他改进以使查询运行得更快吗?

PostgreSQL 9.6

【问题讨论】:

  • 您希望每个 tableA.int_type 有多少来自 tableB.int_type 的匹配行? (tableB似乎更大了……)两者的PK/FK关系?
  • @wildplasser 来自 tableB 的所有(大约 8000 万条)记录将转到 tableA(1.2 亿条)。一对一的关系。没有PK/FK关系

标签: sql postgresql performance


【解决方案1】:

你可以做的是避免幂等更新:


UPDATE TableA a
SET date_type = b.date_type
FROM TableB b
WHERE b.int_type = a.int_type
AND a.date_type IS DISTINCT FROM b.date_type  -- <<-- avoid updates with the same value
        ;

而且,也许您假设 A 和 B 之间存在一对一的关系,但 DBMS 没有。 您可以将更新限制为每个目标行最多一个源行:


EXPLAIN
UPDATE TableA a
SET date_type = b.date_type
FROM ( SELECT int_type, date_type
        , row_number() OVER(PARTITION BY int_type) AS rn
        FROM TableB
        ) b
WHERE b.int_type = a.int_type
AND a.date_type IS DISTINCT FROM b.date_type -- <<-- avoid idempotent updates
AND b.rn=1 -- <<-- allow only one update per target row.
        ;

【讨论】:

  • 对索引有什么建议吗?
  • 由于您没有显示索引定义,我无法对此发表评论。
  • 我的索引是:TableA(int_type), TableB(int_type, date_type)
  • 这不是一个定义。请使用 DDL。
【解决方案2】:

对于这个查询:

UPDATE TableA
SET date_type = TableB.date_type
FROM TableB
WHERE TableB.int_type = TableA.int_type

您可以尝试在TableB(int_type, date_type) 上建立索引。

【讨论】:

    猜你喜欢
    • 2017-06-18
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多