Eu tenho uma tabela com um índice de várias colunas e tenho dúvidas sobre a classificação adequada dos índices para obter o desempenho máximo nas consultas.
O cenário:
PostgreSQL 8.4, tabela com cerca de um milhão de linhas
Os valores na coluna c1 podem ter cerca de 100 valores diferentes . Podemos assumir que os valores estão distribuídos igualmente, portanto, temos cerca de 10000 linhas para cada valor possível.
A coluna c2 pode ter 1000 valores diferentes . Temos 1000 linhas para todos os valores possíveis.
Ao pesquisar dados, a condição sempre inclui valores para essas duas colunas; portanto, a tabela possui um índice de várias colunas combinando c1 e c2. Eu li sobre a importância de ordenar corretamente as colunas em um índice de várias colunas se você tiver consultas usando apenas uma coluna para filtragem. Este não é o caso em nosso cenário.
Minha pergunta é esta:
Dado o fato de um dos filtros selecionar um conjunto de dados muito menor, eu poderia melhorar o desempenho se o primeiro índice for o mais seletivo (aquele que permite um conjunto menor)? Eu nunca tinha considerado essa pergunta até ver os gráficos do artigo mencionado:
Imagem retirada do artigo referenciado sobre índices de várias colunas .
As consultas usam valores das duas colunas para filtragem. Não tenho consultas usando apenas uma coluna para filtragem. Todos eles são: WHERE c1=@ParameterA AND c2=@ParameterB
. Também existem condições como esta:WHERE c1 = "abc" AND c2 LIKE "ab%"
fonte
Se, como você diz, as consultas que envolvem essas 2 colunas, são todas verificações de igualdade de ambas as colunas, por exemplo:
não se preocupe com isso. Duvido que haja alguma diferença e, se houver, será insignificante. Você sempre pode testar, é claro, com seus dados e configurações do servidor. Versões diferentes de um DBMS podem se comportar de maneira ligeiramente diferente em relação à otimização.
A ordem dentro do índice importaria para outros tipos de consultas, com verificações de apenas uma coluna ou condições de desigualdade ou condições em uma coluna e agrupamento na outra, etc.
Se eu escolhesse uma das duas ordens, colocaria a coluna menos seletiva em primeiro lugar. Considere uma tabela com colunas
year
emonth
. É mais provável que você precise de umaWHERE year = 2000
condição ou aWHERE year BETWEEN 2000 AND 2013
ou aWHERE (year, month) BETWEEN (1999, 6) AND (2000, 5)
.Uma consulta do tipo
WHERE month = 7 GROUP BY year
pode ter certeza (encontrar pessoas nascidas em julho), mas seria menos frequente. Isso depende, é claro, dos dados reais armazenados na sua tabela. Escolha um pedido por enquanto, diga o(c1, c2)
e você sempre poderá adicionar outro índice posteriormente(c2, c1)
.Atualização, após o comentário do OP:
Esse tipo de consulta se exatamente uma condição de intervalo na
c2
coluna e precisaria de um(c1, c2)
índice. Se você também tiver consultas do tipo reverso:seria bom se você também tivesse um
(c2, c1)
índice.fonte