Optimizar Consultas
SQL-Optimizar Sentencias
Introducción
El lenguaje SQL es no procedimental, es decir, en las sentencias
se indica que queremos conseguir y no como lo tiene que hacer el
interprete para conseguirlo. Esto es pura teoría, pues en
la práctica a todos los gestores de SQL hay que especificar
sus propios truquitos para optimizar el rendimiento.
Por tanto, muchas veces no basta con especificar
una sentencia SQL correcta, sino que además, hay que indicarle
como tiene que hacerlo si queremos que el tiempo de respuesta sea
el mínimo. En este apartado veremos como mejorar el tiempo
de respuesta de nuestro interprete ante unas determinadas situaciones:
Diseño de las tablas
Normaliza las tablas, al menos hasta la tercera forma normal, para
asegurar que no hay duplicidad de datos y se aprovecha al máximo
el almacenamiento en las tablas. Si hay que desnormalizar alguna
tabla piensa en la ocupación y en el rendimiento antes de
proceder.
Los primeros campos de cada tabla deben ser aquellos campos requeridos
y dentro de los requeridos primero se definen los de longitud fija
y después los de longitud variable.
Ajusta al máximo el tamaño de los campos para no desperdiciar
espacio.
Es muy habitual dejar un campo de texto para observaciones en las
tablas. Si este campo se va a utilizar con poca frecuencia o si
se ha definido con gran tamaño, por si acaso, es mejor crear
una nueva tabla que contenga la clave primaria de la primera y el
campo para observaciones.
Gestión y elección de los índices
Los índices son campos elegidos arbitrariamente por el constructor
de la base de datos que permiten la búsqueda a partir de
dicho campo a una velocidad notablemente superior. Sin embargo,
esta ventaja se ve contrarrestada por el hecho de ocupar mucha más
memoria (el doble más o menos) y de requerir para su inserción
y actualización un tiempo de proceso superior.
Evidentemente, no podemos indexar todos los campos
de una tabla extensa ya que doblamos el tamaño de la base
de datos. Igualmente, tampoco sirve de mucho el indexar todos los
campos en una tabla pequeña ya que las selecciones pueden
efectuarse rápidamente de todos modos.
Un caso en el que los índices pueden resultar
muy útiles es cuando realizamos peticiones simultáneas
sobre varias tablas. En este caso, el proceso de selección
puede acelerarse sensiblemente si indexamos los campos que sirven
de nexo entre las dos tablas.
Los índices pueden resultar contraproducentes
si los introducimos sobre campos triviales a partir de los cuales
no se realiza ningún tipo de petición ya que, además
del problema de memoria ya mencionado, estamos ralentizando otras
tareas de la base de datos como son la edición, inserción
y borrado. Es por ello que vale la pena pensarselo dos veces antes
de indexar un campo que no sirve de criterio para búsquedas
o que es usado con muy poca frecuencia por razones de mantenimiento.
Campos a Seleccionar
En la medida de lo posible hay que evitar que las sentencias SQL
estén embebidas dentro del código de la aplicación.
Es mucho más eficaz usar vistas o procedimientos almacenados
por que el gestor los guarda compilados. Si se trata de una sentencia
embebida el gestor debe compilarla antes de ejecutarla.
Seleccionar exclusivamente aquellos que se necesiten
No utilizar nunca SELECT * por que el gestor debe leer primero la
estructura de la tabla antes de ejecutar la sentencia
Si utilizas varias tablas en la consulta especifica siempre a que
tabla pertenece cada campo, le ahorras al gestor el tiempo de localizar
a que tabla pertenece el campo. En lugar de SELECT Nombre, Factura
FROM Clientes, Facturacion WHERE IdCliente = IdClienteFacturado,
usa: SELECT Clientes.Nombre, Facturacion.Factura WHERE Clientes.IdCliente
= Facturacion.IdClienteFacturado.
Campos de Filtro
Se procurará elegir en la cláusula WHERE aquellos
campos que formen parte de la clave del fichero por el cual interrogamos.
Además se especificarán en el mismo orden en el que
estén definidos en la clave.
Interrogar siempre por campos que sean clave.
Si deseamos interrogar por campos pertenecientes a indices compuestos
es mejor utilizar todos los campos de todos los indices. Supongamos
que tenemos un índice formado por el campo NOMBRE y el campo
APELLIDO y otro índice formado por el campo EDAD. La sentencia
WHERE NOMBRE='Juan' AND APELLIDO Like '%' AND EDAD = 20 sería
más optima que WHERE NOMBRE = 'Juan' AND EDAD = 20 por que
el gestor, en este segundo caso, no puede usar el primer índice
y ambas sentencias son equivalentes por que la condición
APELLIDO Like '%' devolvería todos los registros.
Orden de las Tablas
Cuando se utilizan varias tablas dentro de la consulta hay que tener
cuidado con el orden empleado en la clausula FROM. Si deseamos saber
cuantos alumnos se matricularon en el año 1996 y escribimos:
FROM Alumnos, Matriculas WHERE Alumno.IdAlumno = Matriculas.IdAlumno
AND Matriculas.Año = 1996 el gestor recorrerá todos
los alumnos para buscar sus matriculas y devolver las correspondientes.
Si escribimos FROM Matriculas, Alumnos WHERE Matriculas.Año
= 1996 AND Matriculas.IdAlumno = Alumnos.IdAlumnos, el gestor filtra
las matrículas y después selecciona los alumnos, de
esta forma tiene que recorrer menos registros