Eu tenho uma tabela com um monte de colunas. Entre eles facility_id
e po_date
. Estou escrevendo uma consulta complexa e tenho um índice nessas duas colunas. Você pode ver na saída do planejador abaixo que o Postgres está usando esse índice como a condição do índice quando está se juntando à minha facility
tabela.
Minha dúvida é na verdade em relação à presença de colunas enumeradas na Filter:
linha abaixo. exclude
, verified
, e deleted
não estão no índice referenciado na parte superior e, então, como o Postgres está realmente obtendo os dados nessas colunas? Eu esperava que uma verificação completa da tabela fosse explicitamente citada, mas não há uma à vista em nenhum lugar. Uma varredura de tabela completa pode ser ocultada silenciosamente em um arquivo Filter
?
Esta tabela tem 50 milhões de linhas e estou no Postgres 10. Além disso, essa parte da consulta está em um CTE.
-> Index Scan using clustered_table_facility_id_po_date_idx on clustered_table cp (cost=0.56..1401.08 rows=31929 width=37) (actual time=0.021..5.331 rows=9572 loops=3640)
Index Cond: (facility_id = af.id)
Filter: ((NOT exclude) AND (verified IS NULL) AND (deleted IS NULL))
Rows Removed by Filter: 2819
Por que você esperaria uma varredura completa da tabela quando você tem um índice utilizável?
O otimizador reúne todas as condições, considera os índices disponíveis (e outras formas) e escolhe um "melhor" plano. No seu caso esse plano é:
af.id
(facility_id = af.id)
- isso é possível porque um índice não é uma estrutura autônoma, é baseado em sua tabela e cada item no índice contém um ponteiro para uma linha real da tabelaFilter
parte)Index Scan
significa que o índice é usado para localizar linhas relevantes, mas isso não significa que a tabela não seria tocada, apenas que ela não seria totalmente verificada.Existe a possibilidade de um
Index Only Scan
- quando o índice contém todas as colunas relevantes (não apenas aquelas em ON/WHERE, mas as selecionadas e usadas para ordenar, todas as colunas que a consulta precisa da tabela). Nesse caso, a busca da linha completa da tabela pode não ser necessária - mas algumas linhas são buscadas de qualquer maneira, porque a visibilidade da transação não está disponível no nível do índice para todas as linhas, apenas para blocos inteiros (um problema um pouco complexo).