Utilizamos esto de una forma muy limitada en los procedimientos almacenados.
El problema es que el motor de base de datos no puede mantener un buen plan de consulta para él. Cuando se trata de una gran cantidad de datos, esto puede tener un grave impacto negativo en el rendimiento.
Sin embargo, para conjuntos de datos más pequeños (yo diría que menos de 1000 registros, pero eso es una suposición) debería estar bien. Tendrá que probar en su entorno particular.
Si está en un procedimiento almacenado, es posible que desee incluir algo así como una opción WITH RECOMPILE
para que plan is regenerated on each execution. Esto agrega (ligeramente) al tiempo de cada ejecución, pero en varias ejecuciones puede reducir el tiempo de ejecución promedio. Además, esto permite que la base de datos inspeccione la consulta real y "short circuit" las partes que no son necesarias en cada llamada.
Si está creando directamente su SQL y transfiriéndolo, le sugiero que haga que la parte que construye su sql sea un poco más inteligente para que solo incluya la parte de la cláusula where que realmente necesita.
Otra ruta que puede considerar es utilizar las consultas de UNION ALL en lugar de los parámetros opcionales. Por ejemplo:
SELECT * FROM Teacher WHERE (TeacherId = @TeacherID)
UNION ALL
SELECT * FROM Teacher WHERE (@TeacherId = -1)
Esto realmente logra exactamente lo mismo; sin embargo, el plan de consulta es almacenable en caché. También hemos usado este método en algunos lugares y hemos visto mejoras en el rendimiento con respecto al uso WITH RECOMPILE. No hacemos esto en todas partes porque algunas de nuestras consultas son extremadamente complicadas y prefiero tener un impacto en el desempeño que complicarlas aún más.
Sin embargo, al final debes hacer muchas pruebas.
Hay una segunda parte aquí que debe reconsiderar. SELECT *
. It is ALWAYS preferable to actually name the columns you want returned y para asegurarse de que está solo devolviendo las que realmente necesitará. Mover datos a través de los límites de la red es muy costoso y, en general, puede obtener una buena cantidad de impulso de rendimiento simplemente especificando exactamente lo que desea. Además, si lo que necesita es muy limitado, a veces puede hacer covering indexes para que el motor de base de datos ni siquiera tenga que tocar las tablas subyacentes para obtener los datos que desea.
George, no puedes imaginarte cuán "caliente" es tu pregunta. Acabas de crear una excelente combinación de "mejores prácticas" y "SQL" en una sola pregunta. Agregué +1, agregaría +100 si pudiera. –
Por lo general, escribo dos consultas separadas, tal como sugiere @Jeff O. También es posible que desee leer sobre el rastreo de parámetros. SQL dinámico y RECOMPILE pueden ser más caros en este caso; solo tenemos dos escenarios distintos. –