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?

SeanVDH
fonte
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.

marc_s
fonte
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
Martin Smith
fonte
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