Supondo que eu tenha uma tabela X com 12 colunas. Em minhas consultas, estou filtrando essas condições:
select * from x where a=@a and b=@b
select * from x where a=@b and b=@b and c=@c
select * from x where a=@b and b=@b and d=@d
select * from x where a=@b and b=@b and e=@e
Esta tabela é uma tabela muito ativa e preciso evitar o bloqueio. Se eu precisar criar índices nesta tabela, devo criar 4 índices como este:
(a,b) (include columns)
(a,b,c) (include columns)
(a,b,d) (include columns)
(a,b,e) (include columns)
Ou assim:
(a,b) (include columns)
(c)
(d)
(e)
Ou crie 1 índice (a,b,c,d,e) (inclua colunas)
Estas são as contagens de valores distintos para cada coluna. linhas totais 1446631, a = 366279, b= 96, c = 6, e = 2, d= 11098
Se todos os seus padrões de consulta incluírem filtros em
a
eb
, e a tabela for muito gravada, sugiro testar um único índice que se pareça com este:O motivo é que é necessário manter um único índice em vez de três ou quatro, e a seletividade da terceira coluna no filtro provavelmente não adicionará muitos benefícios adicionais às consultas individuais, pois as duas primeiras colunas já filtram a maior parte da tabela (bem , na verdade, a primeira coluna, já que a segunda coluna tem poucos valores distintos). Você pode monitorar as consultas e ver se algum padrão ou valor de parâmetro específico leva a estimativas terrivelmente ruins, tempos de execução longos ou avisos de índice ausentes. Suspeito que não porque, novamente, com base na densidade que você citou, isso deve levar a intervalos muito pequenos, desde que suas consultas usem filtros em
a
eb
ou, no mínimo,a
.Vou enfatizar que onde você vai acabar não será uma resposta simples "oh, isso é claramente o que você deve fazer". Você precisará testar seu hardware, seus dados e seus padrões de consulta (leitura e gravação) para determinar o(s) melhor(es) índice(s) para sua carga de trabalho.
Como em todas as coisas, depende. Especificamente sobre a cardinalidade das colunas. Se a combinação de colunas
a
eb
for única, você realmente só precisa de um índice(a,b)
. Se estiver próximo (digamos <100 linhas cada), você provavelmente ficará bem. Por outro lado, digamos quec
tenha alta cardinalidade (grande número de valores possíveis) ed
baixa cardinalidade (baixo número de valores possíveis). Você pode criar apenas criar(a,b,c)
. Isso cobrirá a consulta específica usandoa
,b
ec
. Ele também cobrirá com a mesma facilidade uma consulta usando apenasa
eb
. E paraa
,b
ed
chegará perto. O SQL se aproximará usandoa
eb
e, em seguida, pode verificar as linhas restantes, uma vez qued
não será de muita ajuda de qualquer maneira.Todas as coisas sendo iguais e assumindo uma cardinalidade razoável de cada uma, eu criaria o seguinte.
A consulta usando apenas
a
eb
será coberta pelas demais. Supondo que todas as outras colunas sejam cobertas nas colunas de inclusão, é claro.