24/7/13

Mejorar consultas SQL

Antes de nada, debemos tener en cuenta a la hora de realizar una consulta:

- Evitar hacer joins innecesarios

- Al hacer select, es conveniente no usar "Select * from" , nos traeremos solo los campos que vams a necesitar, porque el gestor debe leer primero la estructura de la tabla antes de ejecutar la sentencia.

- Mucho cuidado con el order by, group by o between que consumen bastantes recursos.

- Las subconsultas suelen necesitar mucho tiempo de proceso.

- Las condiciones (tanto de filtro como de join) deben ir siempre en el orden en que esté definido el índice. Si no hubiese índice por las columnas utilizadas, se puede estudiar la posibilidad de añadirlo, ya que tener índices extra sólo penaliza los tiempos de inserción, actualización y borrado, pero no de consulta.

- Los filtros de las consultas deben ser lo más específicos y concretos posibles. Es decir: es mucho más específico poner WHERE campo = 'a' que WHERE campo LIKE '%a%'. Es muy recomendable utilizar siempre consultas que filtren por la clave primaria u otros campos indexados.

- Evitar la condiciones IN ( SELECT…) sustituyéndolas por joins: cuando se utiliza un conjunto de valores en la clausula IN, se traduce por una condición compuesta con el operador OR. Esto es lento, ya que por cada fila debe comprobar cada una de las condiciones simples. Suele ser mucho más rápido mantener una tabla con los valores que están dentro del IN, y hacer un join normal. Por ejemplo, esta consulta:
     
                                                                    SELECT *
                                                                      FROM datos
                                                                    WHERE campo IN ('a', 'b', 'c', 'd', ... , 'x', 'y', 'z');

Se puede sustituir por la siguiente consulta, siempre que la tabla "letras" contenga una fila por cada   valor contenido en el conjunto del IN:
                                                                    SELECT *                                                                              FROM datos d, letras l                              
                                                                     WHERE d.campo = l.letra;

También hay que tener cuidado cuando se mete un SELECT dentro del IN, ya que esa consulta puede retornar muchas filas, y se estaría cayendo en el mismo error. Normalmente, una condición del tipo "WHERE campo IN (SELECT...)" se puede sustituir por una consulta con join.

- Una condición negada con el operador NOT desactiva los índices

- Una consulta cualificada con la cláusula DISTINCT debe ser ordenada por el servidor aunque no se incluya la cláusula ORDER BY.

- Para comprobar si existen registros para cierta condición, no se debe hacer un SELECT COUNT(*) FROM X WHERE xxx, sino que se hace un SELECT DISTINCT 1 FROM X WHERE xxx. De este modo evitamos al servidor que cuente los registros. 

A la hora de diseñar una tabla:
  • Normalizar 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.

No hay comentarios :

Publicar un comentario