Tengo dos consultas casi idénticas ejecutándose en la misma instancia de SQL Server 2005:
- La primera es la
SELECT
consulta original generada por LINQ (lo sé, lo sé ... No soy el desarrollador de la aplicación, solo el DBA :). - El segundo es exactamente el mismo que el primero, se agregó un
OPTION (RECOMPILE)
al final.
Nada más ha sido cambiado.
El primero tarda 55 segundos cada vez que se ejecuta.
El segundo toma 2 segundos.
Ambos conjuntos de resultados son idénticos.
¿Por qué esta pista generaría una ganancia tan dramática en el rendimiento?
La entrada de Books Online RECOMPILE
no ofrece una explicación muy detallada:
Indica al Motor de base de datos de SQL Server que descarte el plan generado para la consulta después de que se ejecute, lo que obliga al optimizador de consultas a volver a compilar un plan de consulta la próxima vez que se ejecute la misma consulta. Sin especificar RECOMPILE, el Motor de base de datos almacena en caché los planes de consulta y los reutiliza. Al compilar planes de consulta, la sugerencia de consulta RECOMPILE utiliza los valores actuales de cualquier variable local en la consulta y, si la consulta está dentro de un procedimiento almacenado, los valores actuales pasan a cualquier parámetro.
RECOMPILE es una alternativa útil para crear un procedimiento almacenado que utiliza la cláusula WITH RECOMPILE cuando solo se debe volver a compilar un subconjunto de consultas dentro del procedimiento almacenado, en lugar de todo el procedimiento almacenado. Para obtener más información, consulte Volver a compilar procedimientos almacenados. RECOMPILE también es útil cuando crea guías de plan. Para obtener más información, consulte Optimización de consultas en aplicaciones implementadas mediante guías de plan.
Dado que mi consulta tiene muchas variables locales, supongo que SQL Server puede (seriamente) optimizarla cuando uso la OPTION (RECOMPILE)
sugerencia de consulta.
Por todas partes que miro, la gente dice que OPTION (RECOMPILE)
debería evitarse. La explicación de esto es que, en general, al usar esta sugerencia, SQL Server no puede reutilizar este plan de ejecución y, por lo tanto, tiene que perder el tiempo volviéndolo a compilar cada vez.
(Pero) Dada la gigantesca ventaja de rendimiento, me inclino a pensar que usar esta sugerencia de consulta esta vez sería algo bueno.
¿Debo usarlo? Si no, ¿hay alguna manera de forzar a SQL Server a usar un mejor plan de ejecución sin esta sugerencia y sin alterar la aplicación?