Tanto si desarrollamos como si administramos SQL Server, antes o después nos encontraremos con problemas de Parameter Sniffing, o lo que es lo mismo, problemas de rendimiento de Procedimientos Almacenados debido a la reutilización de Planes de Ejecución para parámetros de entrada no apropidados. En esta ocasión, vamos a comentar la cláusula OPTIMIZE FOR UNKNOWN, disponible desde SQL Server 2008, una alternativa más para enfrentarnos al Parameter Sniffing.
Aunque ya lo comentamos en el anterior artículo sobre Parameter Sniffing, esta situación se presenta con Procedimientos Almacenados (o consultas parametrizadas) que tienen la peculiaridad de que su Plan de Ejecución más óptimo depende en gran medida de los parámetros de entrada. En consecuencia, si ejecutamos por primera vez dicho Procedimiento Almacenado o consulta parametrizada, se generará (compilará) el Plan de Ejecución en función de dichos valores de entrada, de tal modo que para las sucesivas ejecución, se reutilizará dicho Plan de Ejecución. El problema, es que el Plan de Ejecución que está cacheado y que estamos reutilización, puede ser muy poco beneficioso para posteriores ejecuciones con otros valores de entrada, llegando en ocasiones a apreciarse una brutal pérdida de rendimiento.
¿Cómo lo solucionamos? En el anterior artículo, comentamos algunas posibles soluciones o Workarounds. En esta ocasión vamos a comentar otra más, la cláusula OPTIMIZE FOR UNKNOWN.
La cláusula OPTIMIZE FOR UNKNOWN , al ser utilizada en una consulta, intentará generar un Plan de Ejecución más genérico, que incluso podríamos llamar mediocre, pero que en muchos casos, permitirá que no existan una diferencia tan grande de ejecución en función de los parámetros de entrada, y sin necesidad de tener que recompilar en cada ejecución. Es por ello, que se trata de una alternativa interesante frente al Parameter Sniffing, lo que no quita, que deberemos utilizarlo con mucho cuidado y comprobar previamente su funcionamiento.
OPTIMEZE FOR UNKNOWN es muy cómodo de utilizar, pero evidentemente, utilizar un Plan de Ejecución “genérico”, en ocasiones no será un problema y conseguiremos evitar grandes desviaciones negativas en las ejecuciones de nuestros procedimiento, pero en otras ocasiones, quizás no sea tan interesante su utilización, todo depende del código TSQL y de los posibles valores de entrada que puedan llegar en diferentes ejecuciones.
Por último, antes de acabar, quería aprovechar algunos enlaces de interés sobre este tema, para quienes desee profundizar algo más:
Poco más por hoy. Como siempre, confío que la lectura resulte de interés.