Estou tentando ajustar o desempenho de uma consulta que temos no SQL Server 2014 Enterprise.
Eu abri o plano de consulta real no SQL Sentry Plan Explorer e posso ver em um nó que ele tem um predicado de busca e também um predicado
Qual é a diferença entre Seek Predicate e Predicate ?
Observação: posso ver que há muitos problemas com este nó (por exemplo, as linhas Estimated vs Actual, o IO residual), mas a pergunta não se relaciona a nada disso.
Vamos lançar um milhão de linhas em uma tabela temporária junto com algumas colunas:
Aqui eu tenho um índice clusterizado (por padrão) na
PK
coluna. Há um índice não clusterizadoCOL1
que tem uma coluna de chaveCOL1
e incluiCOL2
.Considere a seguinte consulta:
Aqui não estou usando
BETWEEN
porque Aaron Bertrand está rondando essa questão.Como o SQL Server deve otimizar essa consulta? Bem, eu sei que o filtro em
PK
reduzirá o conjunto de resultados para cinco linhas. O SQL Server pode usar o índice clusterizado para pular para essas cinco linhas em vez de ler todos os milhões de linhas da tabela. No entanto, o índice clusterizado possui apenas a coluna PK como coluna-chave. Uma vez que a linha é lida na memória, precisamos aplicar o filtro emCOL2
. Aqui,PK
é um predicado de busca eCOL2
é um predicado.O SQL Server encontra cinco linhas usando o predicado de busca e reduz ainda mais essas cinco linhas para uma linha com o predicado normal.
Se eu definir o índice clusterizado de forma diferente:
E execute a mesma consulta, recebo resultados diferentes:
Nesse caso, o SQL Server pode buscar usando as duas colunas na
WHERE
cláusula. Exatamente uma linha é lida da tabela usando as colunas-chave.Para mais um exemplo, considere esta consulta:
O índice IX_174860_IX é um índice abrangente porque contém todas as colunas necessárias para a consulta. No entanto, apenas
COL1
é uma coluna chave. O SQL Server pode procurar com essa coluna para localizar as 1.000 linhas com umCOL1
valor correspondente. Ele pode filtrar ainda mais essas linhas naCOL2
coluna para reduzir o resultado final definido para 0 linhas.