一次更改,Postgres查询将变得极其缓慢

问题描述

我有查询,除其他事项外,我需要将discussions.client_first_responded_at转换为给定的时区,每行都不同。如果我将对users.time_zone_offset的引用替换为静态'-06:00'::INTERVAL查询将在一秒钟内执行,但是对users.time_zone_offset的动态引用则需要约120秒。

我想念什么?

SELECT client_id
FROM programs
INNER JOIN users ON users.id = programs.coach_id
WHERE programs.id IN (
  SELECT COALESCE(discussions.parent_id,calls.parent_id) AS program_id
  FROM categorizations
  LEFT OUTER JOIN discussions ON discussions.id = categorizations.categorizable_id AND categorizations.categorizable_type = 'discussion'
  LEFT OUTER JOIN calls ON calls.id = categorizations.categorizable_id AND categorizations.categorizable_type = 'Call'
  WHERE categorizations.categorizable_type = 'discussion' OR categorizations.categorizable_type = 'Call'
  AND COALESCE(
    discussions.client_first_responded_at::timestamptz AT TIME ZONE users.time_zone_offset::INTERVAL,calls.start_time::timestamptz
  ) BETWEEN '2020-09-01' AND '2020-09-30'
);

UPD:

Hash Join  (cost=1.47..250840.61 rows=3542 width=8) (actual time=35.419..61810.027 rows=2266 loops=1)
  Hash Cond: (programs.coach_id = users.id)
  Join Filter: (SubPlan 1)
  Rows Removed by Join Filter: 4821
  Buffers: shared hit=3087792
  ->  Seq Scan on programs  (cost=0.00..368.84 rows=7084 width=20) (actual time=0.008..11.890 rows=7087 loops=1)
        Buffers: shared hit=298
  ->  Hash  (cost=1.21..1.21 rows=21 width=40) (actual time=0.015..0.015 rows=21 loops=1)
        Buckets: 1024  Batches: 1  Memory Usage: 9kB
        Buffers: shared hit=1
        ->  Seq Scan on users  (cost=0.00..1.21 rows=21 width=40) (actual time=0.004..0.008 rows=21 loops=1)
              Buffers: shared hit=1
  SubPlan 1
    ->  Hash Right Join  (cost=777.19..2168.01 rows=7477 width=4) (actual time=0.007..7.887 rows=7516 loops=7087)
          Hash Cond: (discussions.id = categorizations.categorizable_id)
          Join Filter: ((categorizations.categorizable_type)::text = 'discussion'::text)
          Rows Removed by Join Filter: 3473
          Filter: (((categorizations.categorizable_type)::text = 'discussion'::text) OR (((categorizations.categorizable_type)::text = 'Call'::text) AND (COALESCE((timezone((users.time_zone_offset)::interval,(discussions.client_first_responded_at)::timestamp with time zone))::timestamp with time zone,(calls.start_time)::timestamp with time zone) >= '2020-09-01 00:00:00+02'::timestamp with time zone) AND (COALESCE((timezone((users.time_zone_offset)::interval,(calls.start_time)::timestamp with time zone) <= '2020-09-30 00:00:00+02'::timestamp with time zone)))
          Rows Removed by Filter: 2578
          Buffers: shared hit=3087493
          ->  Seq Scan on discussions  (cost=0.00..751.46 rows=18746 width=20) (actual time=0.003..1.842 rows=15668 loops=7087)
                Buffers: shared hit=3087252
          ->  Hash  (cost=647.28..647.28 rows=10393 width=25) (actual time=13.355..13.355 rows=13090 loops=1)
                Buckets: 16384  Batches: 1  Memory Usage: 763kB
                Buffers: shared hit=241
                ->  Hash Left Join  (cost=300.68..647.28 rows=10393 width=25) (actual time=3.476..10.083 rows=13090 loops=1)
                      Hash Cond: (categorizations.categorizable_id = calls.id)
                      Join Filter: ((categorizations.categorizable_type)::text = 'Call'::text)
                      Rows Removed by Join Filter: 2303
                      Buffers: shared hit=241
                      ->  Seq Scan on categorizations  (cost=0.00..319.32 rows=10393 width=13) (actual time=0.006..2.455 rows=13090 loops=1)
                            Filter: (((categorizable_type)::text = 'discussion'::text) OR ((categorizable_type)::text = 'Call'::text))
                            Buffers: shared hit=123
                      ->  Hash  (cost=199.19..199.19 rows=8119 width=20) (actual time=3.462..3.462 rows=8119 loops=1)
                            Buckets: 8192  Batches: 1  Memory Usage: 509kB
                            Buffers: shared hit=118
                            ->  Seq Scan on calls  (cost=0.00..199.19 rows=8119 width=20) (actual time=0.005..1.766 rows=8119 loops=1)
                                  Buffers: shared hit=118
Planning Time: 0.643 ms
Execution Time: 61811.118 ms
Hash Join  (cost=3537.47..4289.98 rows=4825 width=8) (actual time=111.743..122.572 rows=4371 loops=1)
  Hash Cond: (programs.coach_id = users.id)
  Buffers: shared hit=1931
  ->  Hash Join  (cost=3535.95..4273.46 rows=4825 width=12) (actual time=111.627..120.637 rows=4371 loops=1)
        Hash Cond: (programs.id = COALESCE(discussions.parent_id,calls.parent_id))
        Buffers: shared hit=1930
        ->  Seq Scan on programs  (cost=0.00..658.50 rows=9650 width=20) (actual time=0.011..4.880 rows=9656 loops=1)
              Buffers: shared hit=562
        ->  Hash  (cost=3350.83..3350.83 rows=14810 width=8) (actual time=111.573..111.580 rows=4371 loops=1)
              Buckets: 16384  Batches: 1  Memory Usage: 282kB
              Buffers: shared hit=1368
              ->  HashAggregate  (cost=3202.73..3350.83 rows=14810 width=8) (actual time=107.495..109.868 rows=4371 loops=1)
                    Group Key: COALESCE(discussions.parent_id,calls.parent_id)
                    Buffers: shared hit=1368
                    ->  Hash Left Join  (cost=1688.78..3165.70 rows=14810 width=8) (actual time=34.242..97.144 rows=19275 loops=1)
                          Hash Cond: (categorizations.categorizable_id = calls.id)
                          Join Filter: ((categorizations.categorizable_type)::text = 'Call'::text)
                          Rows Removed by Join Filter: 6869
                          Filter: (((categorizations.categorizable_type)::text = 'discussion'::text) OR (((categorizations.categorizable_type)::text = 'Call'::text) AND (COALESCE((timezone('-06:00:00'::interval,(calls.start_time)::timestamp with time zone) >= '2020-09-01 00:00:00+00'::timestamp with time zone) AND (COALESCE((timezone('-06:00:00'::interval,(calls.start_time)::timestamp with time zone) <= '2020-09-30 00:00:00+00'::timestamp with time zone)))
                          Rows Removed by Filter: 7674
                          Buffers: shared hit=1368
                          ->  Hash Right Join  (cost=1046.24..2467.57 rows=21181 width=25) (actual time=21.970..62.581 rows=26949 loops=1)
                                Hash Cond: (discussions.id = categorizations.categorizable_id)
                                Join Filter: ((categorizations.categorizable_type)::text = 'discussion'::text)
                                Rows Removed by Join Filter: 8461
                                Buffers: shared hit=1057
                                ->  Seq Scan on discussions  (cost=0.00..997.71 rows=31771 width=20) (actual time=0.183..8.541 rows=32064 loops=1)
                                      Buffers: shared hit=680
                                ->  Hash  (cost=781.47..781.47 rows=21181 width=13) (actual time=21.720..21.721 rows=26949 loops=1)
                                      Buckets: 32768  Batches: 1  Memory Usage: 1444kB
                                      Buffers: shared hit=377
                                      ->  Seq Scan on categorizations  (cost=0.00..781.47 rows=21181 width=13) (actual time=0.012..11.631 rows=26949 loops=1)
                                            Filter: (((categorizable_type)::text = 'discussion'::text) OR ((categorizable_type)::text = 'Call'::text))
                                            Buffers: shared hit=377
                          ->  Hash  (cost=458.35..458.35 rows=14735 width=20) (actual time=12.205..12.206 rows=14720 loops=1)
                                Buckets: 16384  Batches: 1  Memory Usage: 876kB
                                Buffers: shared hit=311
                                ->  Seq Scan on calls  (cost=0.00..458.35 rows=14735 width=20) (actual time=0.016..6.914 rows=14720 loops=1)
                                      Buffers: shared hit=311
  ->  Hash  (cost=1.23..1.23 rows=23 width=8) (actual time=0.065..0.066 rows=23 loops=1)
        Buckets: 1024  Batches: 1  Memory Usage: 9kB
        Buffers: shared hit=1
        ->  Seq Scan on users  (cost=0.00..1.23 rows=23 width=8) (actual time=0.048..0.054 rows=23 loops=1)
              Buffers: shared hit=1
Planning Time: 1.010 ms
Execution Time: 123.511 ms

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)