Gostaria de saber qual seria a melhor prática na criação de índices para esses tipos de consultas:
select count(*) from my_table where high_granularity_column = $1 and low_granularity_column in ($2, $3)
Espera low_granularity_column
-se que tenha entre 5 e 15 valores distintos e nem sempre tenha a mesma condição de pesquisa, portanto, usá-la para uma condição de índice parcial não é uma opção. Não se espera que a coluna seja usada para classificação e geralmente é um text
tipo de dado de até 10 caracteres (por exemplo, uma coluna "status").
O objetivo é que o BD execute uma varredura somente de índice sempre que possível. Eu testei ambos os índices e eles têm desempenho similar:
create index idx_composite on my_table(high_granularity_column, low_granularity_column);
create index idx_with_include on my_table(high_granularity_column) include (low_granularity_column);
Minha pergunta é: qual é a melhor abordagem em termos de manutenção de índice para operações de inserção e atualização?
Além disso, estou esquecendo de algo em termos de desempenho de pesquisa em que um índice é melhor que o outro para conjuntos de dados maiores (por exemplo, 1 milhão de linhas em my_table
)?
Com o segundo índice com a
INCLUDE
cláusula, o PostgreSQL precisa escanear todas as entradas de índice wherehigh_granularity_column = $1
e então descartar aquelas ondelow_granularity_column
não atendem à sua condição.Com o primeiro índice, o PostgreSQL verificará apenas as entradas de índice que correspondem a ambas as condições, que são menos numerosas.
Então o primeiro índice deve vencer, no que diz respeito ao desempenho. O segundo índice tem um melhor fan-out, porque
low_granularity_column
não é armazenado nas entradas não-folha, então o índice pode ser mais raso — no entanto, essa vantagem potencial não será perceptível, porque você só desce no índice duas vezes. No que diz respeito à manutenção do índice, ambos os índices devem ser igualmente caros.Se você não consegue medir um desempenho melhor com o primeiro índice, isso pode ter duas causas:
O número de linhas correspondentes
high_granularity_column = $1
é tão baixo que a diferença realmente não importa.Você se esqueceu da
VACUUM
tabela, e as muitas buscas de heap na tabela são tão caras que ofuscam a diferença de desempenho das varreduras de índice.