O índice não clusterizado ausente já faz parte do índice clusterizado


9

Estou depurando uma consulta de execução lenta e no plano de execução é sugerido um índice não clusterizado, com impacto 51.6648. No entanto, o índice não agrupado em cluster inclui apenas colunas que já estão no índice clusterizado de chave primária (PK).

Isso pode ser devido à ordem das colunas no índice? ou seja, se as colunas no índice clusterizado não estão na ordem do mais seletivo para o mínimo, existe a possibilidade de um índice não clusterizado melhorar o desempenho?

Além disso, o índice não agrupado em cluster contém apenas duas das três colunas PK com a terceira adicionada como uma coluna incluída. É a includeoutra razão pela qual uso do índice não agrupado poderia ser mais ideal?

Abaixo está um exemplo das estruturas de tabela com as quais estou trabalhando:

Tabelas-

Retailers (
    RetailerID int PK, 
    name ...)

Retailer_Relation_Types (
    RelationType smallint PK, 
    Description nvarchar(50) ...)

Retailer_Relations (
    RetailerID int PK FK, 
    RelatedRetailerID int PK FK, 
    RelationType smallint PK FK, 
    CreatedOn datetime ...)

A tabela Retailer_Relationspossui o seguinte índice PK composto e índices sugeridos

CONSTRAINT PK_Retailer_Relations 
PRIMARY KEY CLUSTERED (
    RetailerID ASC, 
    RelatedRetailerID ASC, 
    RelationType ASC
    ) ON [PRIMARY]

CREATE NONCLUSTERED INDEX <NameOfIndex> 
ON Retailer_Relations (
    RetailerID, 
    RelationType
    ) 
INCLUDE (
    RelatedRetailerID
    )

Respostas:


12

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:

insira a descrição da imagem aqui

Planejar com o índice, usando o índice remove o operador de classificação

insira a descrição da imagem aqui


11
Obrigado Randi, vou marcar isso como a resposta, mas só queria perguntar. Você está dizendo que a sugestão de Índice ausente está baseada no Plano de execução estimado? Peço isso, pois é exibido no Plano de execução real no SS2016.
Fletch

11
Gostaria de saber se é isso que você estava dizendo, obrigado por esclarecer.
Fletch
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.