lunes, 22 de diciembre de 2008

COMPARATIVA DE RENDIMIENTO


Desde la semana pasada está disponible la nueva versión del Editor Sql (1.3). Una de las mejoras en dicho complemento es la posibilidad de obtener estadísticas de tiempo de ejecución, de los 'Lotes' sql, lo que permite realizar comparativas de rendimiento entre distintas sentencias.
A continuación expongo un ejemplo de Lote preparado para evaluar la velocidad de ejecución de distintos códigos, sobre la base de datos Neptuno.mdb. Solo comentar : para que los resultados sean fiables, es conveniente ejecutar el lote más de una vez.

---- Evitar funciones en el lado izquierdo de la expresión -----
------------------------------------------------------------------------

/*
Obtenemos los pedidos del mes de marzo, convirtiendo
los valores de FechaPedido mediante la función Month,
y comparando el resultado con un valor : 3
*/

Select * From Pedidos Where Month(FechaPedido)=3;

/*
Comparamos si FechaPedido se encuentra entre tres rangos,
que corresponden al mes de marzo de cada ejercicio. La sql
es más compleja y no se adapta dinámicamente si añadimos
nuevos registros (para un ejercicio diferente), pero es mucho
más rápida que la anterior puesto que no necesita procesar
con una función todos los registros.
*/

Select * From Pedidos
Where
FechaPedido Between #03/01/1996# And #03/31/1996#
Or
FechaPedido Between #03/01/1997# And #03/31/1997#
Or
FechaPedido Between #03/01/1998# And #03/31/1998#;

-------- Utilizar expresiones apropiadas al tipo de dato -------
-----------------------------------------------------------------------

/*
Obtenemos los pedidos cuya cantidad es múltiplo de 10,
empleando para ello un operador de texto (Like).
*/

Select * From [Detalles de pedidos]
Where Cantidad like '%0';

/*
Obtenemos los pedidos cuya cantidad es múltiplo de 10,
empleando para ello una función numérica. El rendimiento
mejora con respecto a la sql anterior.
*/

Select * From [Detalles de pedidos]
Where Cantidad Mod 10 = 0;

----------- Comparativa consultas de no coincidentes ---------
-----------------------------------------------------------------------

Select * From Pedidos
Where IdCliente Not In (Select IdCliente From Clientes);

Select Pedidos.*
From Pedidos Left Join Clientes
On Pedidos.IdCliente = Clientes.IdCliente
Where Clientes.IdCliente Is Null;

Select Pedidos.* From Pedidos
Where Not Exists
(Select IdCliente From Clientes Where Clientes.IdCliente = Pedidos.IdCliente);

/*
La sql más rápida la obtenemos al emplear Left Join,
a continuación Where Exists, y el método con peor
rendimiento es utilizar el operador IN.
*/


---------- Comparativa uso de Like frente a InStr() -----------
----------------------------------------------------------------------

Select * From Pedidos Where IdCliente Like '%bo%';

Select * From Pedidos Where InStr(1, IdCliente, 'bo') > 0;

/*
Aún cuando el uso del comodín '%' al principio del valor a
buscar, impide que Access utilice el índice, el operador
Like es mucho más eficiente que procesar cada registro
con la función InStr
*/

------------ Comparativa Distinct versus Group By ------------
----------------------------------------------------------------------

Select Distinct FechaPedido, FechaEntrega, FechaEnvío
From Pedidos;

Select FechaPedido, FechaEntrega, FechaEnvío
From Pedidos
Group By FechaPedido, FechaEntrega, FechaEnvío;

/*
... es más rápido Distinct que Group By ...
*/

--- Comparativa relacionar tablas en clausulas From o Where --
--------------------------------------------------------------------------

Select NombreProducto, NombreCompañía
From Productos Inner Join Proveedores
On Productos.IdProveedor = Proveedores.IdProveedor;

Select NombreProducto, NombreCompañía
From Productos, Proveedores
Where Productos.IdProveedor = Proveedores.IdProveedor;

/*
El rendimiento es análogo.
*/

¡ FELIZ NAVIDAD !

Ramon Poch. Terrassa, a 22/12/2008.