A tabela Retailer_Relations possui o seguinte índice PK composto e índices sugeridos -
Embora índices ausentes possam ser úteis e definitivamente funcionem, eu não gastaria muito tempo com índices ausentes, essas dicas são criadas no plano de execução estimado, não no plano de execução real.
Mais precisamente, essas dicas de índice são baseadas na premissa de reduzir o custo do Query Bucks ™ usado pelos operadores no plano. O otimizador calcula os custos estimados e adiciona dicas de índice ausentes de acordo.
Como resultado, eles podem estar muito errados. Se você não tiver certeza se isso vai ajudar, a melhor coisa a fazer é testar a situação antes e depois. Você pode fazer isso adicionando a instrução
SET STATISTICS IO, TIME ON;
antes de executar a consulta.
Além disso, você poderia usar statisticsparser para torná-lo mais fácil de ler estas estatísticas.
Isso pode ser devido à ordem das colunas no índice?
Isso está correto, a criação do índice ausente pode melhorar a seletividade nas consultas, por exemplo, se sua consulta estiver assim:
SELECT RelatedRetailerID
FROM Retailer_Relations
WHERE
RetailerID = 5 AND
RelationType = 20;
ou assim:
SELECT RelatedRetailerID
FROM Retailer_Relations
ORDER BY
RetailerID,
RelationType;
O raciocínio por trás disso é que ambos os índices poderiam procurar no RetailerID, essa parte não vai mudar. Mas e se filtros / pedidos extras forem aplicados no RelationType? Estaria em todo o lugar no índice clusterizado, como resultado do terceiro valor da chave, não do segundo valor da chave. E, como sabemos, é o segundo valor-chave no NCI.
Ok, mas quando ou como o índice não clusterizado melhoraria a consulta?
Alguns casos podem ser:
- Se o relationshipType filtrar muitos valores, a E / S residual poderá ser alta, resultando na possível necessidade do índice não clusterizado (Consulta nº 1)
- A ordenação nas duas colunas ocorre (unidirecional) e o conjunto de resultados é grande (consulta 2).
- Como o @AaronBertrand mencionou: se a diferença de tamanho do IC comparada ao NCI for considerável, a adição do NCI reduzirá as páginas lidas pelas consultas que se beneficiam dele.
Nota lateral da NCI
Como observação lateral, não é exatamente necessário adicionar as colunas-chave à lista de inclusão na sua NCI, pois as colunas-chave do IC são automaticamente incluídas em todos os índices Não agrupados.
Você pode optar por fazê-lo se não tiver certeza se o índice em cluster permanecerá o mesmo e desejar que a coluna seja sempre incluída.
Em relação à consulta em si, se você adicionou o plano de execução via PasteThePlan , poderíamos fornecer mais informações sobre a indexação / melhoria da consulta.
Teste
Crie tabela e adicione algumas linhas
CREATE TABLE Retailer_Relations (
RetailerID int ,
RelatedRetailerID int ,
RelationType smallint,
CreatedOn datetime,
CONSTRAINT PK_Retailer_Relations
PRIMARY KEY CLUSTERED (
RetailerID ASC,
RelatedRetailerID ASC,
RelationType ASC
) ON [PRIMARY])
DECLARE @I Int = 1
WHILE @I < 1000
BEGIN
INSERT INTO Retailer_Relations(RetailerID,RelatedRetailerID,RelationType,CreatedOn)
VALUES(@I,@I,@I,GETDATE()
)
set @I += 1
END
Consulta nº 1
SELECT RelatedRetailerID
FROM Retailer_Relations
WHERE
RetailerID = 5 AND
RelationType = 20;
Planejar sem índice aqui
Enquanto está fazendo uma busca, está fazendo uma busca no RetailerID. Posteriormente, ele está emitindo um predicado de E / S residual no RelationType
Adicione o índice
CREATE NONCLUSTERED INDEX IX_TEST
ON Retailer_Relations (
RetailerID,
RelationType
)
INCLUDE (
RelatedRetailerID
)
O predicado residual se foi, tudo acontece em um predicado de busca, nas duas colunas.
Plano de execução
Com a segunda consulta, a ajuda adicional do índice se torna ainda mais óbvia:
SELECT RelatedRetailerID
FROM Retailer_Relations
ORDER BY
RetailerID,
RelationType;
Planeje sem o índice, com um operador Classificar:
Planejar com o índice, usando o índice remove o operador de classificação