Mesa:
Address (
AddressID bigint,
Street VARCHAR(150),
City VARCHAR(200),
State CHAR(2),
State VARCHAR(5)
)
Tamanho da tabela: 5 GB, 60 milhões de linhas.
AdressID
é sequencial.
Observação : 95-98% das consultas usadas são exatamente as mesmas a seguir, com variações do intervalo de AddressID na WHERE
cláusula:
SELECT AddressID, Street , City, State, State
WHERE AddressID > someNumber AND AddressID < anotherNumber
Pergunta : Valerá a pena criar um índice clusterizado em AddressID
? Ou será contraproducente, já que pelo menos 95% das consultas selecionam todas as colunas da tabela?
Com base nas informações acima, existem outras boas opções para criar qualquer índice que ajude a melhorar o desempenho da consulta acima? Pensei em criar um índice de cobertura, mas não seria como uma varredura de tabela, já que incluirá todas as colunas da tabela?
Para o ponto de vista de Erik, vale a pena ter um índice quando você precisa aplicar qualquer tipo de predicado na tabela (por exemplo
JOIN
, cláusulas , ) eWHERE
também pode ser útil ao usar ou , independentemente de aplicar um predicado à tabela. O raciocínio é que um índice classifica logicamente os dados em que sua chave é definida - normalmente com uma estrutura de dados B-Tree. Pense em um índice como uma lista telefônica, que é classificada.HAVING
GROUP BY
ORDER BY
Um índice clusterizado está classificando logicamente os próprios dados da tabela . Um índice não clusterizado armazena uma cópia dos dados definidos nesse índice e classifica essa cópia de dados com base em sua chave. Como um índice clusterizado é essencialmente a tabela, todas as colunas estão implicitamente disponíveis nesse índice, nos nós de nível folha. E é basicamente um brinde , já que não está armazenando uma cópia dos dados na tabela, é a tabela.
Isso torna um índice clusterizado definido
(AddressID)
muito adequado para o seu caso de uso, porque você precisa de todas as colunas da tabela e está filtrando sua tabela com umaWHERE
cláusula que sempre faz referência a esse campo. Um índice permite que o SQL Engine busque diretamente o nó B-Tree que inicia o intervalo de seusWHERE
valores de cláusula. Sem um, toda a tabela de 60 milhões de linhas precisaria ser verificada primeiro, antes que ela pudesse filtrá-la apenas para as linhas de que suaWHERE
cláusula precisa.O outro benefício importante de ter um índice clusterizado em sua tabela é se, posteriormente, você precisar adicionar índices não clusterizados adicionais para oferecer suporte a quaisquer outros casos que prediquem sua tabela. Você pode manter alguns desses índices não clusterizados enxutos não incluindo todas as colunas que a consulta está
SELECT
fazendo. Isso ocorre porque o SQL Engine pode aproveitar o índice clusterizado para buscar os campos ausentes, de forma bastante eficiente, depois de filtrar as linhas pelo índice não clusterizado que cobre esse outro predicado. Todo índice não clusterizado armazena implicitamente a chave do índice clusterizado, para que possa procurar qualquer coluna que não tenha armazenado facilmente. Esta etapa de execução é chamadaKey Lookups
. Dependendo do número de linhas que estão sendo retornadas/precisando fazerKey Lookups
vs a largura da tabela/índice, às vezes é mais ideal apenas armazenar as cópias extras desses campos no próprio índice não clusterizado - mas isso é muito situacional eKey Lookups
geralmente funciona bem.A única desvantagem menor de adicionar um índice clusterizado a uma tabela é que há uma pequena quantidade de sobrecarga para o índice gerenciar a si mesmo conforme as linhas são inseridas ou atualizadas com base na chave do índice. Normalmente, os ganhos de desempenho de leitura do índice clusterizado superam em muito essa sobrecarga de gravação. É raro não ter um índice clusterizado em uma tabela. Uma exceção são os casos de uso em que a tabela é sempre lida em sua totalidade e nunca ou raramente atualizada ou excluída, apenas inserida ou truncada - por exemplo, um tipo de tabela de preparação.