0

我们正在尝试从版本 9 系列升级,并有一个破坏交易的慢查询,它在 10 和 11 中运行良好,但在 12 和 13 中慢很多倍。我已经测试了 11 和 12 系列中的次要版本, 次要版本不影响它。

问题在于规划器选择嵌套循环连接而不是它应该使用的哈希连接。

v11 哈希连接:

->  Nested Loop Left Join  (cost=276056.74..285056.52 rows=1714 width=230) (actual time=13519.865..15864.542 rows=57 loops=1)
      Join Filter: (placement_type.placement_type_id = job_order.placement_type_id)
      Rows Removed by Join Filter: 57
      ->  Nested Loop Left Join  (cost=276056.74..284967.78 rows=1714 width=224) (actual time=13519.837..15864.202 rows=57 loops=1)
            ->  Hash Join  (cost=276056.32..284215.53 rows=1714 width=217) (actual time=13519.803..15863.465 rows=57 loops=1)
                  Hash Cond: (ori.order_id = job_order_1.order_id)
                  ->  HashAggregate  (cost=246953.68..250381.92 rows=342824 width=487) (actual time=13397.503..15017.114 rows=1053462 loops=1)

v12 嵌套循环:

->  Nested Loop Left Join  (cost=304636.78..316645.32 rows=1716 width=230) (actual time=17799.135..152297.231 rows=57 loops=1)
      Join Filter: (placement_type.placement_type_id = job_order.placement_type_id)
      Rows Removed by Join Filter: 57
      ->  Nested Loop Left Join  (cost=304636.78..316556.50 rows=1716 width=224) (actual time=17799.111..152296.749 rows=57 loops=1)
            ->  Nested Loop  (cost=304636.37..315803.37 rows=1716 width=217) (actual time=17799.075..152295.098 rows=57 loops=1)
                  Join Filter: (job_order_1.order_id = ori.order_id)
                  Rows Removed by Join Filter: 60047277

我们测试环境中的升级过程是使用 pg_upgrade 完成的,并在测试此查询之前进行全面分析。

那么12有什么变化呢?

4

1 回答 1

0

感谢 PG 邮件列表中的人们,他们应该为这个答案而受到赞誉。

在 PostgreSQL 12 之前,使用 CTE 创建了一个“优化障碍”。在某些情况下,幸运的是,这会为查询带来良好的性能,否则规划器无法成功估计。

添加 MATERIALIZED 关键字 ( WITH ... AS MATERIALIZED (...)) 会强制执行旧行为。所以这是解决性能问题的一种方法。另一种方法是优化给规划器带来麻烦的 SQL,当规划器决定重新安排 CTE 的处理时,这可能会出现。

于 2021-02-22T19:44:49.483 回答