PostgreSQL запрос на изменение плана - PullRequest
0 голосов
/ 27 февраля 2020

У меня есть запрос PostgreSQL, в котором есть предложение With (CTE), в котором указаны входные значения (тип данных int). Для этого запроса количество выходных строк будет таким же, как и количество входных значений, указанных в предложении With. В предложении with нет объединения, в главном предложении select есть только две таблицы.

Этот запрос выполняется менее чем за 500 миллисекунд, пока число входных значений не станет 531. Если оно выходит за пределы, требуется около 15 секунд (даже для 532 входных значений).

В плане объяснения я мог видеть изменения плана для основного запроса с «Nested l oop left join» на «Ha sh right join» когда количество входных значений превышает 531.

Редактировать: добавлено объяснение и анализ для обоих сценариев ios.

Если количество входных значений равно 532

Sort  (cost=45221.67..45221.68 rows=2 width=322) (actual time=15371.553..15371.576 rows=532 loops=1)
  Sort Key: fc.flashnumber DESC
  Sort Method: quicksort  Memory: 95kB
  CTE t
    ->  GroupAggregate  (cost=0.43..4489.54 rows=3586 width=22) (actual time=3.876..21.531 rows=532 loops=1)
          Group Key: flashcomment.flashnumber
          ->  Index Scan using flashcomment_ndx01 on flashcomment  (cost=0.43..4435.68 rows=3601 width=22) (actual time=3.861..18.628 rows=713 loops=1)
                Index Cond: ((flashnumber)::text = ANY ('{2020022601503,2020022601502,2020022601498,2020022601497,2020022601496,2020022601495,2020022601494,2020022601493,2020022601492,2020022601491,2020022601490,2020022620200219007292020021900630,2020021900629,2020021900628}'::text[]))
                Filter: (is_parent = 'N'::bpchar)
  ->  Nested Loop Left Join  (cost=0.43..40732.12 rows=2 width=322) (actual time=3.919..15366.603 rows=532 loops=1)
        Join Filter: (upper((fc.stamp_userid)::text) = upper((up.user_id)::text))
        Rows Removed by Join Filter: 19483968
        ->  Nested Loop  (cost=0.43..39103.24 rows=1 width=299) (actual time=3.897..34.879 rows=532 loops=1)
              ->  CTE Scan on t  (cost=0.00..71.72 rows=3586 width=90) (actual time=3.879..23.038 rows=532 loops=1)
              ->  Index Scan using flashcomment_ndx01 on flashcomment fc  (cost=0.43..10.87 rows=1 width=299) (actual time=0.012..0.016 rows=1 loops=532)
                    Index Cond: ((flashnumber)::text = (t.flashnumber)::text)
                    Filter: ((is_parent = 'N'::bpchar) AND (t.mx_gmttime = stamp_gmttime))
                    Rows Removed by Filter: 0
        ->  Seq Scan on user_profile up  (cost=0.00..1000.86 rows=35886 width=23) (actual time=0.003..6.865 rows=36625 loops=532)
Planning time: 3.728 ms
Execution time: 15371.683 ms

Если количество входных значений 530

Sort  (cost=44660.91..44660.91 rows=2 width=322) (actual time=37.383..37.406 rows=530 loops=1)
  Sort Key: fc.flashnumber DESC
  Sort Method: quicksort  Memory: 95kB
  CTE t
    ->  GroupAggregate  (cost=0.43..4473.75 rows=3572 width=22) (actual time=3.922..8.892 rows=530 loops=1)
          Group Key: flashcomment.flashnumber
          ->  Index Scan using flashcomment_ndx01 on flashcomment  (cost=0.43..4420.10 rows=3587 width=22) (actual time=3.906..8.644 rows=709 loops=1)
                Index Cond: ((flashnumber)::text = ANY ('{2020022601503,2020022601502,2020022601498,2020022601497,2020022601496,2020022601495,2020022601494,2020022601493,2020022601492,2020022601491,2020022601490,2020022601489,2020021900629,2020021900628}'::text[]))
                Filter: (is_parent = 'N'::bpchar)
  ->  Hash Right Join  (cost=38960.19..40187.14 rows=2 width=322) (actual time=14.613..34.816 rows=530 loops=1)
        Hash Cond: (upper((up.user_id)::text) = upper((fc.stamp_userid)::text))
        ->  Seq Scan on user_profile up  (cost=0.00..1000.86 rows=35886 width=23) (actual time=0.008..6.647 rows=36625 loops=1)
        ->  Hash  (cost=38960.17..38960.17 rows=1 width=299) (actual time=14.586..14.586 rows=530 loops=1)
              Buckets: 1024  Batches: 1  Memory Usage: 49kB
              ->  Nested Loop  (cost=0.43..38960.17 rows=1 width=299) (actual time=3.947..14.203 rows=530 loops=1)
                    ->  CTE Scan on t  (cost=0.00..71.44 rows=3572 width=90) (actual time=3.925..9.069 rows=530 loops=1)
                    ->  Index Scan using flashcomment_ndx01 on flashcomment fc  (cost=0.43..10.88 rows=1 width=299) (actual time=0.009..0.009 rows=1 loops=530)
                          Index Cond: ((flashnumber)::text = (t.flashnumber)::text)
                          Filter: ((is_parent = 'N'::bpchar) AND (t.mx_gmttime = stamp_gmttime))
                          Rows Removed by Filter: 0
Planning time: 3.721 ms
Execution time: 37.531 ms

Можете ли вы помочь мне, как улучшить производительность?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...