Sorry por la demora en escribir, entre los ultimos dias en el trabajo y preparando el viaje a Nicaragua he estado con poco tiempo libre.
1- Los stored proedures anidados vs IF statements.
2- Rendimiento de Ad-hoc queries vs stored procedures.
Sobre el tema 1:
El problema al que se refieren es mas general que solo el caso de code branching, de echo puede ocurrir con el mas simple de los queries:
select * from dbo.Test where CategoryID = @p1;
El problema es conocido en el mundo de las bases de datos como "parameter sniffing". Esto puede ocurrir tanto en SPs como en Ad-hoc queries que sean parametrizado, y si los Ad-hoc que usan no son parametrizados tienen otros muchos peores problemas como "cache bloat" y "CPU splikes" (pero estos son otros temas)
Basicamente lo que ocurre cuando hay queries parametrizados es que el DB engine intenta reusar el mismo plan de ejecucion para todos los queries y puede darse el caso de que un buen plan de ejecucion para un valor del parametro sea muy malo para otro valor, esto debido a la distribucion de los datos.
Ha varias maneras de lidiar con este problema si se presenta, los mas comunes son:
- with recompile (a nivel de SP)
- option recompile (a nivel de query)
- option optimize for (a nivel de query)
- query hints
- plan guides
Ninguna de las soluciones es perfecta (puede hacer mucho mayor uso del CPU), pero te pueden tirar un buen cabo cuando hay problemas en el sistema. Si el query o SP que tiene problemas se ejecuta pocas veces el option recompile o with recompile son la mejor opcion. Si, por el contrario se ejecuta muchas veces el option optimize for para algun valor en especifico o usando la clausula unknown pude darte un plan de ejecucion que sea lo suficientemente bueno para todos los casos. Las dos ultimas opciones son solo recomendadas para resolver un problema puntual en produccion (stop the bleeding) pero a largo plazo siempre dan problemas y no son recomendadas.
Es un tema super interesante y hay que ir caso por caso, en general la recomendacion es no tocar nada de eso excepto en el caso que tengas problemas, una excepcion a esto son SPs o queries que se ejecuten en un ambiente de reporting/datawarehouse que el costo de parsing y recompilacion es despreciable comparado al costo de ejecucion y es relativamente normal usar las opciones 1 o 2 mencionadas.
Sobre el tema 2:
Este es un temas mucho mas "caliente", desde el punto de vista del rendimiento la diferencia es minima a favor de los SPs (asumiendo que los queries son parametrizados) y es causada por el parsing de los queries y el network traffic .
Ahora bien existen otros muchos beneficios de usar SPs sobre Ad-hoc queries:
- Operational flexibility: Hay muchas razones por las que puede ser necesario tocar un SP, un ejemplo: Imaginen que de pronto la aplicacion en produccion se pone super lenta, puede ser un plan de ejecucion malo que esta cached. Si, el codigo esta en el SP uno puede simplemente ejecutar un sp_recompile a ese SP y la proxima vez que se ejecute ya se creara un nuevo plan de ejecucion o se puede usar alguna de las tecnicas mencionadas arriba with recompile/option recompile. Esto lo puede hacer el DBA en unos segundos, si por el contrario el codigo esta en la aplicacion:
- Es mucho mas dificil identificarlo,
- Se puede borrar el plan cache pero es un poco mas complicado
- Si hay necesidad de agregar option recompile al query, depende de donde este almacenado el ad-hoc query (en la aplicacion, en un resource file, en la propia BD, alguna otro mecanismo), en general es mas complicado.
- Monitoring: A nivel de SPs es sumamente facil y hay muchas herramientas para monitorear y almacenar estadisticas de rendimiento de los SPs y no es solamente duration, sino tambien CPU usage, IO stats and memory usage. Esta informacion es invaluable para optimizar la aplicacion a nivel de queries no es imposible pero es muchisimo mas complicado.
- Security: El bolao ya menciono esta anteriormente.
- Code maintenance (esta trae bastante debate): Los SPs son codigo y cuando se tienen en algun IDE de base de datos (junto con el esquema) puedes hacer varias cosas similares a las que estamos acostumbrados en C# o Java, por ejemplo buscar dependencias o build el proyecto para ver si no hay errores o warnings. Imaginen que estan haciendo un refactor qu incluye borrar una columna, es mucho mas facil y conveniente compilar un database project y ver los SPs que fallan a tener que buscar en el codigo o resource files donde se usa esa columna.
En mi opinion se debe encontrar un balance donde las operaciones mas sencillas se hagan sin SPs y las mas complejas o que uno sospeche que puedan causar problemas en SPs. El reto es encontrar un mecanismo para que "sencillo" signifique mas o menos lo mismo para todos los developeres y ademas que los DBAs tambien esten contentos con el plan.
Saludos,