Eu tenho uma consulta SQL que estou tentando otimizar:
DECLARE @Id UNIQUEIDENTIFIER = 'cec094e5-b312-4b13-997a-c91a8c662962'
SELECT
Id,
MIN(SomeTimestamp),
MAX(SomeInt)
FROM dbo.MyTable
WHERE Id = @Id
AND SomeBit = 1
GROUP BY Id
MyTable
tem dois índices:
CREATE NONCLUSTERED INDEX IX_MyTable_SomeTimestamp_Includes
ON dbo.MyTable (SomeTimestamp ASC)
INCLUDE(Id, SomeInt)
CREATE NONCLUSTERED INDEX IX_MyTable_Id_SomeBit_Includes
ON dbo.MyTable (Id, SomeBit)
INCLUDE (TotallyUnrelatedTimestamp)
Quando executo a consulta exatamente como escrito acima, o SQL Server verifica o primeiro índice, resultando em 189.703 leituras lógicas e uma duração de 2 a 3 segundos.
Quando inline a @Id
variável e executo a consulta novamente, o SQL Server busca o segundo índice, resultando em apenas 104 leituras lógicas e uma duração de 0,001 segundo (basicamente instantânea).
Eu preciso da variável, mas quero que o SQL use o bom plano. Como solução temporária, coloco uma dica de índice na consulta, e a consulta é basicamente instantânea. No entanto, tento ficar longe de dicas de índice quando possível. Normalmente, presumo que, se o otimizador de consulta não puder fazer seu trabalho, há algo que posso fazer (ou parar de fazer) para ajudá-lo sem dizer explicitamente o que fazer.
Então, por que o SQL Server apresenta um plano melhor quando inline a variável?