Erwin, como essa foi a nossa discussão no tópico de comentários de antes, decidi cutucá-lo um pouco mais ...
Eu tenho uma consulta muito simples de uma tabela de tamanho razoável. Normalmente tenho o suficiente work_mem
, mas nesse caso usei os comandos
SET work_mem = 64;
para definir um muito pequeno work_mem
e
SET work_mem = default;
para definir que minhas work_mem
costas sejam suficientemente grandes para minha consulta.
EXPLIQUE e verifique novamente a condição
Então, executando minha consulta apenas EXPLAIN
como
EXPLAIN
SELECT * FROM olap.reading_facts
WHERE meter < 20;
Eu obtive os resultados para baixo e alto work_mem
:
Baixo work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32)
Recheck Cond: (meter < 20)
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0)
Index Cond: (meter < 20)
Alto work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32)
Recheck Cond: (meter < 20)
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0)
Index Cond: (meter < 20)
Para encurtar a história, EXPLAIN
apenas como esperado, o plano de consulta indica que uma condição Recheck é possível, mas não sabemos se será realmente calculado.
EXPLICAR ANALISAR & Verificar novamente a condição
Quando incluímos ANALYZE
na consulta, os resultados nos dizem mais sobre o que precisamos saber.
Baixo work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32) (actual time=3.130..13.946 rows=51840 loops=1)
Recheck Cond: (meter < 20)
Rows Removed by Index Recheck: 86727
Heap Blocks: exact=598 lossy=836
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0) (actual time=3.066..3.066 rows=51840 loops=1)
Index Cond: (meter < 20)
Alto work_mem
Bitmap Heap Scan on reading_facts (cost=898.92..85632.60 rows=47804 width=32) (actual time=2.647..7.247 rows=51840 loops=1)
Recheck Cond: (meter < 20)
Heap Blocks: exact=1434
-> Bitmap Index Scan on idx_meter_reading_facts (cost=0.00..886.96 rows=47804 width=0) (actual time=2.496..2.496 rows=51840 loops=1)
Index Cond: (meter < 20)
Mais uma vez, como esperado, a inclusão de ANALYZE
nos revela algumas informações muito importantes. No work_mem
caso baixo , vemos que há linhas removidas pela verificação do índice e que temos lossy
blocos de heap.
Conclusão? (ou falta dela)
Infelizmente, parece que, EXPLAIN
por si só, não é suficiente saber se uma verificação de índice será realmente necessária, porque alguns dos IDs de linha estão sendo descartados em favor da retenção de páginas durante a verificação de heap de bitmap.
Usar EXPLAIN ANALYZE
é bom para diagnosticar os problemas com consultas de tamanho moderado, mas se uma consulta estiver demorando muito tempo para ser concluída, a execução EXPLAIN ANALYZE
para descobrir que o índice de bitmap está sendo convertido em perda por insuficiente work_mem
ainda é uma restrição difícil. Eu gostaria que houvesse uma maneira de EXPLAIN
estimar a probabilidade dessa ocorrência a partir das estatísticas da tabela.