Этот Postgres запрос не оптимален? - PullRequest
1 голос
/ 28 апреля 2020

Я столкнулся с проблемой, когда выполнение следующего запроса в Postgres 9.2 занимает очень много времени:

select coalesce(sum(col_a), 0) 
from table_a 
where tid not in ( 
    select distinct tid 
    from table_b 
    where col_b = 13 )

Обратите внимание, что tid является первичным ключом в table_a. Для table_b, tid индексируется и ссылается на table_a как внешний ключ.

Эта проблема в основном возникает, когда диск почти заполнен, и в таблице происходит некоторая переиндексация. Я не эксперт по базам данных, и я не совсем понимаю, в чем проблема.

Может кто-нибудь помочь разобраться в проблеме / скажите, есть ли более оптимальный запрос?

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Я бы порекомендовал NOT EXISTS с правильным индексом . Итак, напишите запрос как:

select coalesce(sum(col_a), 0) 
from table_a a
where not exists (select 1
                  from table_b b
                  where b.tid = a.tid and b.col_b = 13
                 );

Индекс, по которому вы хотите, table_b(tid, col_b):

create index idx_table_b_tid_col_b on table_b(id, col_b);
0 голосов
/ 28 апреля 2020

Я бы попробовал с NOT EXISTS:

select coalesce(sum(a.col_a), 0) 
from table_a a
where not exists (select 1 from table_b b where b.tid = a.tid and b.col_b = 13);

Кроме того, агрегирование также было бы полезно:

select coalesce(sum(a.col_a), 0) 
from table_a a inner join
     table_b b
     on b.tid = a.tid
group by a.tid
having count(*) filter (where b.col_b = 13) = 0;

Еще один вариант - использовать left join:

select coalesce(sum(a.col_a), 0) 
from table_a a left join
     table_b b
     on b.tid = a.tid and b.col_b = 13
where b.tid is null;

Для оптимальной производительности, индекс будет полезным table_a(tid, col_a), table_b(tid, col_b)

...