Se eu tiver uma chave composta feita de 3 colunas, como
constraint some_index unique (parent_store_id, store_type, store_name),
E também preciso poder fazer consultas de seleção com where store_type = ...
ou where store_name = ...
, ainda preciso criar índices separados para cada uma dessas colunas? Ou o índice exclusivo acima resolve esses casos?
Se você tiver um índice exclusivo composto:
Este índice é mais eficaz somente quando a consulta filtra colunas da esquerda para a direita nessa ordem exata.
Então, aqui: essas consultas se beneficiarão do índice:
E essas consultas não usarão o índice de forma eficiente:
Para tais consultas, você deve criar índices separados em store_type ou store_name, dependendo do seu uso.
Observação : Adicionar índices gera sobrecarga de armazenamento e atualização. Portanto, adicione apenas o que for realmente usado em suas consultas.
O tipo de índice padrão é o BTree , que classifica seus
parent_store_id
s, cada um contendo seusstore_type
s classificados, cada um com seusstore_name
s classificados. A busca com base em todas as colunas ou nas colunas iniciais funciona bem. Outras combinações, especialmente as colunas mais à direita, não funcionam bem porque você precisa descer na árvore e coletá-las de cada ramo. Elas são classificadas independentemente umas das outras e são desduplicadas apenas internamente.Dependendo do seu esquema, caso de uso e volumes, em vez de tentar antecipar todos os tipos de consultas e inundar seu banco de dados com uma BTree otimizada separada para cada combinação de colunas, você pode considerar um índice de filtro Bloom — é exatamente para isso que ele serve. Citando a documentação :
Se eu criar seu índice em uma configuração de teste com 100 mil linhas:
demonstração em db<>fiddle
Obtenho 0,3 ms , 6 ms e 9 ms para pesquisas na 1ª, 2ª e 3ª colunas, respectivamente. Se eu substituir por um índice de filtro bloom:
Todas as três buscas levam cerca de 0,9 ms . O resumo é este:
O que significa que você ainda precisa manter o BTree para proteger a exclusividade e o Bloom só pode substituir os índices adicionais.
Se você realmente só tiver que lidar com essas três colunas, manter as poucas BTrees não deve ser um grande problema, mas quanto mais colunas você adicionar e mais variabilidade nos filtros de pesquisa você vir, mais perto estará do caso de uso ideal para o bloom.
Pode ser que sim ou não. Depende de vários fatores:
vacuum
edição,analyze
d,reindex
ed. Uma tabela nova, compacta e organizada é preferível a um índice desatualizado e inchado, e vice-versa.cluster
editado por esse índicewhere
condição faz referência à primeira coluna, mas de certa forma está abordando a tabela inteira, não faz sentido usar o índice, a menos que seja um índice de cobertura.A lista não é exaustiva. Você pode experimentar
set enable_seqscan=off;
e ver que, embora o Postgres consiga obter os valores solicitados usando o índice, a varredura sequencial às vezes é realmente o método mais rápido.Somente se você puder arcar com a pequena, mas diferente de zero, latência adicional em
insert
/update
/delete
, que precisa ser refletida em cada índice, além do espaço para acomodar os índices, além da manutenção dos índices (reindex
que não acontece por si só, eles ficam inchados e desatualizados). Além disso, se você não puder arcar com a diferença no tempo de execução das consultas nas colunas finais.