Eu tenho duas consultas quase idênticas em execução na mesma instância do SQL Server 2005:
- A primeira é a
SELECT
consulta original gerada pelo LINQ (eu sei, eu sei ... eu não sou o desenvolvedor de aplicativos, apenas o DBA :). - O segundo é exatamente o mesmo que o primeiro, adicionado a
OPTION (RECOMPILE)
no final.
Nada mais foi alterado.
O primeiro leva 55 segundos toda vez que é executado.
O segundo leva 2 segundos.
Ambos os conjuntos de resultados são idênticos.
Por que essa dica geraria um ganho tão dramático no desempenho?
A entrada do Books Online RECOMPILE
não oferece uma explicação muito detalhada:
Instrui o Mecanismo de Banco de Dados do SQL Server a descartar o plano gerado para a consulta após a execução, forçando o otimizador de consulta a recompilar um plano de consulta na próxima vez que a mesma consulta for executada. Sem especificar RECOMPILE, o Mecanismo de Banco de Dados armazena em cache os planos de consulta e os reutiliza. Ao compilar planos de consulta, a dica de consulta RECOMPILE usa os valores atuais de quaisquer variáveis locais na consulta e, se a consulta estiver dentro de um procedimento armazenado, os valores atuais serão transmitidos para qualquer parâmetro.
RECOMPILE é uma alternativa útil para criar um procedimento armazenado que usa a cláusula WITH RECOMPILE quando apenas um subconjunto de consultas dentro do procedimento armazenado, em vez de todo o procedimento armazenado, deve ser recompilado. Para obter mais informações, consulte Recompilando procedimentos armazenados. RECOMPILE também é útil quando você cria guias de plano. Para obter mais informações, consulte Otimizando consultas em aplicativos implantados usando guias de plano.
Como minha consulta possui muitas variáveis locais, meu palpite é que o SQL Server pode (seriamente) otimizá-la quando uso a OPTION (RECOMPILE)
dica de consulta.
Em todo lugar que olho, as pessoas estão dizendo que isso OPTION (RECOMPILE)
deve ser evitado. A explicação para isso é geralmente que o uso dessa dica do SQL Server não pode reutilizar esse plano de exceção e, portanto, precisa perder tempo recompilando-o sempre.
(Mas) Dada a gigantesca vantagem de desempenho, estou inclinado a pensar que usar essa dica de consulta desta vez seria uma coisa boa.
Devo usá-lo? Caso contrário, existe uma maneira de forçar o SQL Server a usar um plano de execução melhor sem essa dica e sem alterar o aplicativo?