Tiene razón en estar preocupado por el plan de ejecución que se está almacenando en caché.
Martin ofrece un buen ejemplo que muestra que el plan está en caché y se optimizará para una cierta rama de su lógica la primera vez que se ejecuta. Después de la primera ejecución, ese plan se reutiliza incluso si llama al procedimiento almacenado (sproc) con un parámetro diferente que hace que su flujo de ejecución elija otra rama. Esto es muy malo y matará el rendimiento. He visto esto suceder muchas veces y lleva un tiempo encontrar la causa raíz.
La razón detrás de esto se llama "Parameter Sniffing" y vale la pena investigar.
Una solución común propuesta (una que yo no aconsejo) es dividir su sproc en unos pequeños. Si llama a un sproc dentro de un sproc ese sproc interno obtendrá un plan de ejecución optimizado para el parámetro que se le pasa.
Dividir un sproc en unos pocos más pequeños cuando no hay un buen motivo (una buena razón sería la modularidad) es una solución fea. Martin muestra que es posible recompilar una declaración introduciendo un cambio en el esquema. Usaría OPCIÓN (RECOMPULE) al final de la declaración. Esto le indica al optimizador que realice una recopilación de instrucciones teniendo en cuenta el valor actual de variables: no solo se tienen en cuenta los parámetros, sino también las variables locales que pueden marcar la diferencia entre un plan bueno y uno malo.
Para volver a su pregunta de construir una consulta con una cláusula where diferente según un parámetro.Me gustaría utilizar el siguiente patrón:
WHERE
(@parameter1 is null or col1 = @parameter1 )
AND
(@parameter2 is null or col2 = @parameter2 )
...
OPTION (RECOMPILE)
El lado negativo es que el plan de ejecución de esta declaración no se almacena en caché (no influye en el almacenamiento en caché hasta el punto de la declaración sin embargo) que puede tener un impacto si el sproc se ejecuta muchas veces ya que ahora se debe tener en cuenta el tiempo de compilación. Realizar una prueba con datos de calidad de producción le dará la respuesta si es un problema o no.
Lo bueno es que puede codificar sprocs legibles y legibles y no configurar el optimizador con el pie equivocado.
Otra opción a tener en cuenta es que puede deshabilitar el almacenamiento en caché del plan de ejecución en el nivel sproc (a diferencia del nivel de declaración) que es menos granular y, más importante aún, no tendrá en cuenta el valor de las variables locales al optimizar
Más información en http://www.sommarskog.se/dyn-search-2005.html http://sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries/
¿cuál sería el 'SI ... ELSE .. .' (o 'CASE') ¿contienen exactamente? En algunos casos, es posible y más eficiente abstraer el condicional en parámetros. Usted tiene un plan de ejecución por proceso, por lo que la lógica condicional puede dar como resultado un rendimiento desigual. –