Desempeño en SQL (No 1).

Escrito por Administrator. Publicado en artículos técnicos

Bienvenido a la primera entrega de nuestra serie de artículos Desempeño en SQL.  Pretendemos crear un conjunto de consejos fáciles de implementar, prácticos y sencillos para mejorar el desempeño de sus consultas SQL en Microsoft SQL-Server 2005 y superior.

Evite usar funciones en las cláusulas ON y WHERE

¿Qué diferencia hay entre usar una de estas dos sentencias en un SELECT?

WHERE miCampo LIKE '4444%' .

ó

WHERE LEFT(miCampo,4) = '4444'

El conjunto de datos que ambas condiciones retornan es idéntico, pero el desempeño puede variar enormemente.  El uso de funciones como LEFT en las condiciones de una sentencia WHERE puede impedir el uso de los índices existentes sobre la tabla durante la consulta y afectar negativamente el desempeño.

Veamos un ejemplo concreto.  Tenemos una tabla llamada Persona con 300 registros, y un índice sobre la columna CodigoPostal.  Deseamos obtener todos los registros cuyo código postal inicia con cuatro dígitos ‘4444’.  Esta consulta:

SELECT a.Direccion, a.Ciudad, a.CodigoPostal
FROM dbo.Persona AS a
WHERE ‘4444’ = LEFT(a.CodigoPsotal,4)

Se ejecuta en 2.81 segundos y toma 316 lecturas a disco.  En cambio, si expresamos la consulta de esta forma:

SELECT a.Direccion, a.Ciudad, a.CodigoPostal
FROM dbo.Persona AS a
WHERE a.CodigoPostal LIKE ‘4444%’

Se ejecuta en tan solo 0.31 segundos y toma 3 lecturas a disco.

¿Por qué la diferencia es tan grande?  La primera sentencia no puede utilizar el índice existente sobre la columna aCodigoPostal y por lo tanto debe realizar un barrido de la tabla para evaluar la función LEFT sobre todas y cada una de las filas.  En una tabla con 300 registros hemos economizado el 90% del tiempo de ejecución.  Imagine una tabla con varios millones de registros.

Elija el tipo de datos correcto.

Supongamos que existe una tabla de nombre Empleado con un identificador de tipo alfanumérico llamado Cedula, que es la llave primaria de la tabla (y por lo tanto existe un índice sobre dicha columna).  Sabemos que el SQL puede convertir implícitamente valores numéricos a alfanuméricos, así que estas dos consultas producen el mismo resultado:

SELECT * FROM dbo.Empleado WHERE Cedula = 102340567
SELECT * FROM dbo.Empleado WHERE Cedula = ‘102340567’

Pero la diferencia en desempeño puede ser dramática.  La primera consulta obliga a crear un plan de ejecución con un CAST implícito para convertir el valor numérico a un valor alfanumérico, y esto a su vez ocasiona un barrido completo del índice.

En cambio la segunda consulta, al usar el tipo de datos correcto, permite que el plan de ejecución incluya solamente una búsqueda (un “seek”) en el índice.

En una tabla con 1200 registros, la cantidad de lecturas se reduce a la mitad.  Como de costumbre, a mayor cantidad de registros, mayor será el impacto.

No se pierda nuevos consejos en próximas entregas de esta serie.

  • Paquetes WEB
  • Aplicaciones
  • Apoyo Técnico
  • Sistemas de Pesaje