El rincón de JMACOE

Lentitud con funciones de tabla en SQL Server

Muchos de nosotros debemos de conocer las funciones de SQL Server, su clasificación, como se usan, etc. Además los que administran las base de datos pueden crear funciones para ser utilizadas en las aplicaciones. Si bien son de gran ayuda, existen ciertos criterios a tener en cuenta al momento de construir las consultas, ya que esto puede determinar cuan rápido se devuelvan los datos.

Un caso particular fue lo que me sucedió al momento de querer mostrar un reporte, utilizaba 2 filtros cada uno de ellos con checkbox para poder seleccionar de una lista y mediante la aplicación los enviaba los valores seleccionados en conjunto a una variable. Esta variable mediante una función, llamada listadeenteros_a_tabla, convertía los valores ya sean numéricos o enteros a una tabla, para finalmente ser utilizada dentro de la sentencia WHERE como lo muestra el siguiente ejemplo:

WHERE   Prd.Actividad    = 2
   AND PA.Unidad IN (SELECT number from listardeenteros_a_tabla(@Unidad))
   AND Prd.Periodo IN (SELECT number from listardeenteros_a_tabla(@Periodo))

Entonces al lanzar la ejecución del reporte con esos filtros el tiempo de ejecución de la consulta era demasiado alta, se demoraba mucho y eso no era bueno ni para el usuario que estará impaciente por ver su reporte listo como para nosotros que somos los que desarrollamos las aplicaciones. Entonces comencé a Ejecutar la consulta sin filtros y me cargó más rápido que lo que me demoré en seleccionar toda la consulta. Luego empecé a ir seleccionando uno por uno y me llevé con la sorpresa que al usar el tercer filtro la consulta se volvía pesada (demoraba aun mas) y por ende tediosa. Fue cuando debía de buscar una solución que me permita mostrar mas rápido la información.  La solución fue utilizar tablas temporales, puse el resultado de la consulta hasta donde me cargaba rápido dentro de una tabla temporal, luego en el SELECT final utilice el tercer filtro que me estaba haciendo lenta la consulta. Al final el resultado fue el siguiente:

Select campo1, campo2, campo3,...
INTO #tablatemporal
FROM
...
WHERE       nPrdActividad    = 2

SELECT * 
FROM #tablatemporal
WHERE       nUniOrgCodigo   IN (Select number from listardeenteros_a_tabla(@cUniOrgCodigo))
          AND nPrdCodigo       IN (Select number from listardeenteros_a_tabla(@cPrdCodigo))
ORDER BY escuela,nombres

Entonces luego de esto la consulta se volvió ligera (se ejecuto mas rápido) y estuvo lista para ser enviada al usuario final. El detalle es el siguiente, las funciones se van ejecutando una a una por cada registro evaluado, por eso es preferible usar variables que contengan el resultado de las funciones, o utilizarlas en una consulta final. Entonces ahora sí a tener cuidado con el uso excesivo de tablas temporales.

Comparte y diviertete: