Устранение значительного снижения производительности после обновления до Postgres 12, если используются выражения столбцов - PullRequest
0 голосов
/ 07 апреля 2020

Запрос не возвращает строк, но его время выполнения в Postgres 12 зависит от выражения столбца.

Запрос с выражением столбца

coalesce( (select sum(taitmata) 
 from rid join dok using (dokumnr)
where toode=toode.toode and doktyyp='T' 
and not dok.taidetud and dok.kinnitatud and 
taitmata is not null),0) 

занимает огромное количество времени:

explain analyze select 
    coalesce( (select sum(taitmata) from rid join dok using (dokumnr)
    where toode=toode.toode and doktyyp='T' and not dok.taidetud and dok.kinnitatud and 
    taitmata is not null),0) 
    from toode 
        where toode.ribakood='testmiin'::text
           or toode.nimetus ilike '%'||'testmiin'||'%'            or toode.toode ilike '%'||'testmiin'||'%'           
      or toode.markused ilike '%'||'testmiin'||'%'
           or to_tsvector('english',toode.nimetus) @@ plainto_tsquery('testmiin') 
             or to_tsvector('english',toode.engnimetus) @@  plainto_tsquery('testmiin')  


"Gather  (cost=1000.00..505930.82 rows=153 width=32) (actual time=785.410..785.478 rows=0 loops=1)"
"  Workers Planned: 1"
"  Workers Launched: 1"
"  ->  Parallel Seq Scan on toode  (cost=0.00..10015.31 rows=90 width=21) (actual time=608.346..608.346 rows=0 loops=2)"
"        Filter: (((ribakood)::text = 'testmiin'::text) OR (nimetus ~~* '%testmiin%'::text) OR (toode ~~* '%testmiin%'::text) OR (markused ~~* '%testmiin%'::text) OR (to_tsvector('english'::regconfig, (nimetus)::text) @@ plainto_tsquery('testmiin'::text)) OR (to_tsvector('english'::regconfig, (engnimetus)::text) @@ plainto_tsquery('testmiin'::text)))"
"        Rows Removed by Filter: 7202"
"  SubPlan 1"
"    ->  Aggregate  (cost=3234.63..3234.64 rows=1 width=32) (never executed)"
"          ->  Nested Loop  (cost=11.26..3234.52 rows=43 width=3) (never executed)"
"                ->  Bitmap Heap Scan on rid  (cost=10.84..1191.72 rows=270 width=7) (never executed)"
"                      Recheck Cond: (toode = toode.toode)"
"                      Filter: (taitmata IS NOT NULL)"
"                      ->  Bitmap Index Scan on rid_toode_pattern_idx  (cost=0.00..10.77 rows=312 width=0) (never executed)"
"                            Index Cond: (toode = toode.toode)"
"                ->  Index Scan using dok_pkey on dok  (cost=0.42..7.57 rows=1 width=4) (never executed)"
"                      Index Cond: (dokumnr = rid.dokumnr)"
"                      Filter: ((NOT taidetud) AND kinnitatud AND (doktyyp = 'T'::bpchar))"
"Planning Time: 4.907 ms"
"JIT:"
"  Functions: 24"
"  Options: Inlining true, Optimization true, Expressions true, Deforming true"
"  Timing: Generation 5.168 ms, Inlining 157.637 ms, Optimization 474.786 ms, Emission 304.165 ms, Total 941.756 ms"
"Execution Time: 830.674 ms"

Тот же запрос с простым выражением столбца

1

выполняется во много раз быстрее:

explain analyze select 1
from toode 
    where toode.ribakood='testmiin'::text
       or toode.nimetus ilike '%'||'testmiin'||'%'            
       or toode.toode ilike '%'||'testmiin'||'%'            
       or toode.markused ilike '%'||'testmiin'||'%'            or to_tsvector('english',toode.nimetus) @@ plainto_tsquery('testmiin') 
         or to_tsvector('english',toode.engnimetus) @@
         plainto_tsquery('testmiin')  



"Gather  (cost=1000.00..11030.61 rows=153 width=4) (actual time=178.712..180.697 rows=0 loops=1)"
"  Workers Planned: 1"
"  Workers Launched: 1"
"  ->  Parallel Seq Scan on toode  (cost=0.00..10015.31 rows=90 width=4) (actual time=160.552..160.552 rows=0 loops=2)"
"        Filter: (((ribakood)::text = 'testmiin'::text) OR (nimetus ~~* '%testmiin%'::text) OR (toode ~~* '%testmiin%'::text) OR (markused ~~* '%testmiin%'::text) OR (to_tsvector('english'::regconfig, (nimetus)::text) @@ plainto_tsquery('testmiin'::text)) OR (to_tsvector('english'::regconfig, (engnimetus)::text) @@ plainto_tsquery('testmiin'::text)))"
"        Rows Removed by Filter: 7202"
"Planning Time: 4.131 ms"
"Execution Time: 180.727 ms"

Если имеется больше выражений столбца, разница в производительности увеличивается , Таблица rid, используемая в выражении столбца, содержит 1,8 миллиона строк. Вероятно, снижение производительности может произойти при обновлении с Postgres 9.1 до Postgres 12

Поскольку данные не возвращаются, производительность запроса должна быть такой же. Как это исправить?

...