Recentemente, fiz uma pergunta sobre a melhor estratégia de indexação para uma tabela que deve registrar eventos, em ordem, em relação a um GUID. O GUID é um incômodo, mas é inevitável porque é um FK para outro lugar.
Em termos das consultas que quero fazer, elas são essencialmente da formaSELECT TOP N SomeColumn FROM t WHERE GuidColumn = 'someguid' ORDER BY AutoIncInt DESC
Eu fiz algumas experiências e uma boa abordagem de compensação parece ser:
- Crie a
AutoIncInt
coluna na tabela como a chave de clustering exclusiva - Crie um índice não clusterizado não exclusivo em
GuidColumn
eINCLUDE SomeColumn
No começo eu tinha o índice nonclustering em SomeGuid ASC, AutoIncInt DESC
, pensando que ajudaria a ORDER BY AutoIncInt DESC
parte da consulta mas o plano permaneceu o mesmo quando eu o removi - nenhuma operação de classificação foi necessária e a consulta apenas atingiu o índice NC, fez um top e um select; parece que o SQLServer é de alguma forma inteligente o suficiente para saber, mesmo quando AutoIncInt não é citado no índice de não clustering, há uma maneira de obter facilmente os dados em ordem / calcular facilmente quais últimas N linhas são necessárias para o TOP
Como esse mecanismo funciona na prática? O índice sem cluster tem uma ordem implícita graças à referência ao índice de cluster, de modo que o SQLS possa deduzir rápida e facilmente de quais nós de índice N eu quero a SomeColumn?
Cada linha de nó folha em um índice de árvore b do SQL Server identifica exclusivamente uma única linha na tabela por uma chave exclusiva. Em um índice não clusterizado, essa chave exclusiva consiste nas colunas de chave declaradas mais o localizador de linha. O localizador de linha é a chave do índice clusterizado (incluindo o exclusivo para quando o valor da chave do CI não é exclusivo). Com um heap (sem índice clusterizado na tabela), o localizador de linha é o local físico da linha (arquivo, página, slot).
A
DBCC PAGE
saída deste script de demonstração mostra ambasGuidColumn
eAutoIncInt
como chaves de índice, emboraAutoIncInt
não tenha sido especificado:.Resultados:
Essa arquitetura de índice tem implicações de desempenho positivas para sua consulta porque a
AutoIncInt
coluna não é apenas incluída implicitamente no índice não clusterizado como o localizador de linha, mas também faz parte da chave exclusiva e, portanto, ordenada. Isso permite que o plano de sua consulta use uma busca de índice para oGuidColumn
WHERE
predicado mais uma varredura para trás para aORDER BY...DESC
cláusula.Abaixo está um trecho do plano de consulta real que mostra uma verificação inversa do índice. O índice não clusterizado resultante será o mesmo, independentemente de
AutoIncInt
estar explicitamente especificado como uma coluna de chave.