Em que ponto ter um índice se torna eficiente


9

Encontrei muitos recursos que mencionam que a adição de um índice a uma tabela torna as pesquisas mais rápidas e as inserções mais lentas, mas apenas se a tabela for grande. Isso cria uma troca, que é uma decisão de design, mas deve haver um tamanho aproximado de tabela antes do qual o uso de um índice é absurdo. (10 linhas, por exemplo, provavelmente estão muito abaixo desse limite)

Alguém sabe onde estaria esse limite ou conhece algum recurso que me aponte na direção certa?


Qual é a proporção de leituras / gravações para seu aplicativo? Se você realmente escreve muito, talvez seja o ponto em que você precisa levar em consideração a troca de gravações, mas se for um aplicativo comum, eu adicionaria o índice necessário em 99% dos casos (as tabelas geralmente crescem, dificilmente volte em tamanho).
— Marian

Respostas:


12

O limite exato é realmente difícil de determinar com antecedência.

Uma coisa que a maioria das pessoas subestima são os altos requisitos que um índice deve atender antes que ele se torne um candidato a ser usado em uma consulta.

Um índice eficiente (não clusterizado)

  • oferece grande seletividade , por exemplo, retorna apenas uma porcentagem muito pequena (<1%, <2%) do total de linhas. Se a seletividade não for determinada, o otimizador de consultas do SQL Server provavelmente ignorará esse índice

  • idealmente, deve cobrir a consulta, ou seja, retornar todas as colunas exigidas pela consulta. Se você pode criar um índice que tenha 1 ou 2 colunas de índice e incluir outras (2 a 4) colunas como colunas incluídas e, assim, você pode cobrir uma consulta - é provável que o otimizador de consulta use esse índice. O que também significa: se o seu código está sempre usando SELECT * .....para buscar todas as colunas , a probabilidade de os índices serem usados ​​diminui - de maneira bastante dramática, na verdade

Tenho certeza de que existem muitos outros critérios também - mas acredito que esses dois são os mais críticos. Obviamente, você sempre deve manter seus índices adequadamente mantidos (reorganizar, reconstruir) e garantir que as estatísticas associadas a seus índices estejam atualizadas.

PS: índices não clusterizados em colunas de chave estrangeira são um caso especial; Por padrão, eu sempre recomendaria adicioná-las, pois elas ajudam a acelerar as verificações de integridade referenciais e JOINas restrições de FK. Mas mesmo aqui, é absolutamente válido "estender" esses índices de coluna do FK adicionando algumas colunas adicionais de "inclusão" para torná-los ainda mais úteis.


2
Embora essa resposta possa não responder diretamente à pergunta, ela se sai muito melhor fornecendo os importantes princípios de design do índice e responde à pergunta que eu deveria ter feito em primeiro lugar.
— SeanVDH

6

Você pode ver uma melhoria em um índice com apenas 10 linhas.

No teste a seguir na minha máquina, a versão sem um índice concluída em 10.5segundos e a versão com um índice em 9.8segundos (consistente em 3 execuções).

O índice, nesse caso, consiste apenas em 1 página folha, mas, como a matriz de slots é ordenada em ordem de chave de índice, sua presença permite que o SQL Server retorne apenas a única linha de interesse em vez de realizar uma agregação em todas as 10.

CREATE TABLE T
(
X INT,
Y CHAR(100) NULL
)

INSERT INTO T (X)
SELECT number 
FROM master..spt_values
WHERE type='P' AND number BETWEEN 1 AND 10

set nocount on;

DECLARE @I INT, @X INT

DECLARE @Time DATETIME2(7) = SYSUTCDATETIME()

SET @I = 1
    WHILE (@I < 1000000)
    BEGIN
    SELECT @X = MAX(X)
    FROM T
    SET @I += 1
    END

SELECT DATEDIFF(MICROSECOND, @Time, SYSUTCDATETIME())

CREATE CLUSTERED INDEX IX ON T(X)
SET @Time = SYSUTCDATETIME()
SET @I = 1
    WHILE (@I < 1000000)
    BEGIN
    SELECT @X = MAX(X)
    FROM T
    SET @I += 1
    END

SELECT DATEDIFF(MICROSECOND, @Time, SYSUTCDATETIME())

DROP TABLE T

As inserções são afetadas da mesma forma ou a desaceleração é mínima?
— SeanVDH

@SeanVDH - O exemplo na minha resposta está comparando um índice clusterizado a um heap. Seria lógico que as inserções entre as linhas existentes seriam mais lentas, pois as linhas precisam ir para um local específico e a matriz de slots reescrita também tem a possibilidade de divisões de páginas. Para inserções maiores, os dados também podem ser classificados em ordem de chave de IC, o que é desnecessário ao inserir em um heap. Kimberley Tripp argumenta aqui, porém, que às vezes a inserção em um IC pode ser melhor do que a inserção em um heap.
— Martin Smith

Obrigado pelo artigo, ela apresenta alguns pontos interessantes. Fiquei me perguntando se as inserções seriam afetadas tão dramaticamente quanto as seleções na tabela pequena, mas você está certo, a troca deve ser semelhante no início, como seria mais tarde.
— SeanVDH
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.