Um índice ou dois?

11

Eu tenho o seguinte índice criado em uma tabela no meu banco de dados:

CREATE INDEX [idx_index1]
on [table1]
(col1, col2, col3)

O servidor está sugerindo o seguinte índice 'ausente':

CREATE INDEX [idx_index2]
on [table1]
(col1, col2)
INCLUDE (col3, col4, col5, col6....)

Parece-me lógico alterar a definição de índice existente para incluir as colunas sugeridas, em vez de criar um novo índice que precise ser mantido. Uma consulta que seleciona col1 e col2 pode usar o índice1 com a mesma eficácia que o índice2. Estou correto ou talvez esteja faltando alguma coisa?

paulH
fonte

Respostas:

12

E assim entra a arte de ajustar o desempenho e estratégias de indexação ...

Parece-me lógico alterar a definição de índice existente para incluir as colunas sugeridas

Vou pegar sua cotação e escrever uma terceira definição de índice:

create index [idx_index3]
on [table1] (col1, col2, col3)
include (col4, col5, col6....);

Essa deve ser a CREATE INDEXdeclaração que corresponde à sua declaração citada.

Isso pode muito bem ser uma solução prudente, mas depende . Aqui estão alguns exemplos quando digo que depende.

Se você tiver uma carga de trabalho comum que consiste principalmente em consultas como esta:

select col1, col2, col3
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

Então seu idx_index1índice seria sólido. Perfeitamente estreito, é um índice que satisfaz essa consulta sem dados estranhos (sem levar em consideração a definição do índice clusterizado, se houver).

Mas se você tiver uma carga de trabalho que consiste em consultas principalmente como as seguintes:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2;

Em seguida, idx_index2seria sábio, como é que é chamado de índice de cobertura evitando a necessidade de um back-chave de pesquisa para o índice de cluster (ou uma pesquisa de volta RID para a pilha). Essa definição de índice não clusterizado abrangeria apenas todos os dados de que a consulta precisa.

Com sua recomendação, seria adequado para uma consulta como a seguinte:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

Sua idx_index3recomendação seria um índice de cobertura que atenda aos critérios de pesquisa da consulta acima.

O ponto que estou tentando abordar é em uma pergunta isolada como esta que não podemos responder a isso definitivamente. Tudo depende de qual é a carga de trabalho comum e frequente. É claro que você sempre pode definir todos esses três índices para lidar com cada tipo de consulta de amostra, mas depois coloca em questão a manutenção necessária para manter esses índices atualizados (pense: INSERTs, UPDATEs, DELETEs). Essa é a sobrecarga dos índices.

Você precisa dissecar e avaliar a carga de trabalho e determinar onde as vantagens serão melhores. Se a primeira consulta de amostra é a mais comum, de longe, sendo executada dezenas de vezes por segundo, e há uma consulta muito pouco frequente como a terceira consulta de amostra, não faria sentido inchar as páginas no nível da folha do índice com o comando INCLUDEcolunas não chave. Tudo depende da sua carga de trabalho.

Se você entende estratégias prudentes de indexação e entende sua carga de trabalho comum, aplicando as duas opções, poderá encontrar o melhor caminho a seguir.

Thomas Stringer
fonte
Vou ter que digerir isso por um tempo, mas parece uma boa resposta. Suponho que foi um erro de digitação que o 'index3' que você definiu tem col3 como uma coluna de igualdade E uma coluna incluída?
PaulH
Sim :-) Boa captura. Eu editei isso.
Thomas Stringer
Sem mencionar que, se a tabela tiver apenas as colunas 1 a 6, é muito bobo indexar 1 e 2 e incluir 3-5.
Kenneth Fisher
1
@ KennethFisher - por que isso seria bobo? Parece bastante razoável se a estrutura do banco de dados e a carga de trabalho o justificarem. Por exemplo, se você tiver uma consulta que selecione as colunas 1 a 5 com base nos valores das colunas 1 e 2, e talvez a coluna 6 seja uma coluna nvarchar (max) com a qual você não deseja inchar seu índice.
PaulH
1
@paulH Provavelmente é apenas a minha opinião, mas no momento em que você adicionou colunas suficientes para incluir que o seu índice tem mais de 90% de suas colunas na tabela, você aumentou o índice até o ponto em que a leitura extra deve ir para a tabela em si não é tão importante. Agora certamente existem exceções. Se as colunas 1 a 5 são todas int e col6 é um varchar (max), eu posso fazer isso. Mas, em geral, eu os olhava MUITO cuidadosamente.
Kenneth Fisher
7

Você está realmente correto e descobriu por que é importante para um DBA sempre revisar as "sugestões" apresentadas pelas DMVs de índice ausentes etc.

Considere que as sugestões oferecidas pelas DMVs de índice ausentes são apresentadas isoladamente, o que significa que o SQL Server decidiu que um índice da estrutura recomendada beneficiaria a consulta, independentemente de outras estruturas de índice já existirem.

John Sansom
fonte
3

Um pouco mais, sobre uma das implicações da resposta de Thomas:

Ele disse:

É claro que você sempre pode definir todos esses três índices para lidar com cada tipo de consulta de amostra, mas depois coloca em questão a manutenção necessária para manter esses índices atualizados (pense: INSERTs, UPDATEs, DELETEs). Essa é a sobrecarga dos índices.

Então, outra grande questão se torna: com que frequência a tabela é atualizada?

Considere primeiro um exemplo de uma tabela que é constantemente atualizada, como por exemplo, uma ORDERStabela de varejo que reflete a atividade do consumidor do site ... lá, você deseja ter consciência de ter vários índices, porque eles aumentam o trabalho realizado por atualizações constantes e, portanto, afeta constantemente o desempenho do banco de dados.

Por outro lado, considere uma tabela que é atualizada apenas como parte da configuração do site - a tabela sendo atualizada UMA VEZ para a maioria dos valores e os valores raramente adicionados - lá, as lentidões da atualização praticamente não são consideradas. Vários índices podem desacelerar as recriações e reorganizações de índices do banco de dados, mas desde que sejam rápidos o suficiente, SENTIR-SE GRATUITO: se vários índices aceleram as leituras, faça isso.

Um caso intermediário pode ser uma tabela que normalmente é atualizada apenas em um processo em lote durante a noite. Lá, a desaceleração da atualização de vários índices não afetaria o desempenho diurno - eles apenas afetariam (1) o tempo gasto para executar a manutenção noturna em lote, (2) o desempenho de quaisquer processos simultâneos e (3) o tempo gasto para tarefas de manutenção de banco de dados, como reorganização do índice. Portanto, desde que os processos nessas três arenas sejam executados com rapidez suficiente para você ... crie os índices que aceleram as consultas.

HTH ...

Doug_Ivison
fonte