optimizacion de consultas en mysql
Hablando de la optimizacion de consultas en mysql en clave Heavy
Hace un par de entradas os estuve hablando de mySQL, mariaDB, los siete enanitos, pikachu, borjamari y pocholo, y todo el resto de la tribu, pero no me he parado ni a hablar de las consultas, como si todo el mundo supiese de qué estoy hablando. Personalmente opino que este sistema gestor es muy interesante, simplemente porque es uno de los más extendidos. Y, de hecho, me siento bastante cómodo con él, es uno de mis favoritos aun a pesar de sus carencias y de que mySQL AB, la empresa propietaria, ya no sea una empresa de esas que molan. Podría extenderme sobre por qué mySQL (Y evidentemente todos sus Forks y herederos, por absurdos que puedan parecer) me parecen una gran opción, pero me limitaré a decir que…
.. hasta a los helloween les surge la necesidad de hacer consultas. Y si a unos personajacos como a ellos, me he dicho, les interesa, cómo no voy a hacer una entrada sobre el tema.
Así soy yo: Pensamiento puro. Pero dejémonos de historias, pongamos el modo tontaco a FALSE y vayamos a lo bonico, que es donde está el meollo.
Empezando: ¿Qué es una consulta?
Una consulta, o en la lengua negra de Mordor una query, es una revisión o búsqueda de datos en una base de datos; y en este caso es en SQL, y más concretamente para mySQL. Voy a ir poniéndoos algunos casos muy genéricos cuya intención es dar un primer acercamiento para alguien que sepa algo de mySQL, y quizá ayudarle a caer en algunos pequeños errores que son mejorables en todo este proceloso tema de la optimizacion de consultas en tu mySQL.
Usa LIMIT siempre que puedas
Conseguir limitar la cantidad de resultados es uno de los recursos más interesantes que puede ofrecernos mySQL. Hacer esto en otros sistemas es un pisto, y nos permite escalar muy fácilmente nuestra base de datos cuando tenemos muchos registros y sólo necesitamos algunos de ellos en un número que conocemos de antemanos. Ejemplos:
SELECT nombre FROM clientes WHERE dni = "123456" LIMIT 1
Con esto tan tonto logramos que la base de datos busque un resultado único, por lo que el tipo de búsqueda que hace es diferente a si busca varios posibles resultados: es más eficiente. Vayamos con otro ejemplo:
SELECT nombre, apellidos FROM clientes ORDER BY nombre LIMIT 10
Ejemplo típico para cuando estás paginando con un número concreto de registros por pantalla.
Lo mismo podríamos hacer con otros tipos, como podrían ser UPDATE o DELETE, para asegurarnos que no vamos a cargarnos nada que no estemos toqueteando.
Evita el comodín
Si amigos, porque puede pareceros muy divertido hacer un SELECT (*), pero si vas a necesitar sólo unos campos es mejor que saques sólo esos campos. Porque cuando tu base de datos crezca, algo que tarde unos milisegundos pasará a tardar unos segundos, y la aplicación se quedará colgada. Puede parecer una tontada, pero no lo es, y de veras que un detalle tan sencillo puede ayudaros en la optimizacion de consultas. Ejemplos:
SELECT nombre, apellidos, edad, dni FROM clientes
mejor esto que
SELECT * FROM clientes
No a ORDER BY RAND()
Cuando tienes muy pocas tuplas en una tabla, podéis caer en el error de que es una buena idea ordenar de manera aleatoria unos cuantos resultados (O todos). Nada más lejos de la verdad: ORDER BY RAND() fuerza a que se organicen los resultados al azar para cada tupla, y eso hace mucho mucho mucho consumo extra de recursos en la base de datos. Lo cierto es que hay pocas soluciones simples a esto. Siempre que sea posible, intentad mantener la lógica en la base de datos. Recordad: La base de datos es vuestra amiga.
SQL_SMALL_RESULT
Si usas una consulta con las cláusulas GROUP BY o DISTINCT y sabes de antemano que va a ser una consulta pequeña, SQL_SMALL_RESULT crea tablas temporales de acceso muy rápido y acelera mucho el acceso a los datos.
PROCEDURE ANALYSE
Vale, me habéis pillado: esto no puede hacerse en una query, sino que tiene que ver con prestar atención a las tablas y cómo están definidas. Podrás obtener un montón de útiles sugerencias sobre la estructura de la tabla, donde te recomendará, en base al uso que tenga en ese momento la tabla, la estructura concreta. Si tienes muchos campos en que permites NULL y es MyISAM te propondrá que los pases a NOT NULL con default 0, o si tienes como clave primaria INT y no tienes muchos campos te propondrá que pases a MEDIUMINT. Entre otras fantásticas ideas y, aunque no sea una optimización de query por si misma, os va a venir de fábula al ir empezando.
Haz JOIN sin usar JOIN
Hay mucha tontería sobre los INNER JOIN, LEFT JOIN, NATURAL JOIN y demás zoroastradas varias, pero en verdad yo os digo que la mejor manera de hacer un JOIN es con los alias de siempre, cuando sea posible y cuando los datos que buscamos sean esos. Ejemplo:
SELECT c.nombre, c.apellidos, ca.direccion_completa FROM clientes c, clientes_avanzado ca WHERE c.id=ca.id_cliente
Normalmente la mayoría de búsquedas se van a obtener bien así, es decir, que al hacer el producto cartesiano vamos a buscar todos los que están en los dos grupos. Si buscamos todos los que no, va a depender del tamaño de las tablas e incluso de los campos que queramos recuperar, que nos convenga más hacer esto en una subconsulta excluyendo, o hacer dierectamente un JOIN específico.
Hasta el infinito y más allá
Esto que os he contado es un somero aterrizaje, asumiendo muchas cosas como que son asín, pero mucho puede variar dependiendo de lo que realmente tengáis entre manos. Lo mejor es que, en el caso de cada consulta que vayáis a lanzar, uséis EXPLAIN para que os amplíe mucha información con la que tomar determinadas decisiones para añadir o quitar índices, hacer uniones por otros campos… Los datos los devolverá en una sencilla tabla. Ejemplo:
EXPLAIN SELECT c.nombre, c.apellidos, ca.direccion_completa FROM clientes c, clientes_avanzado ca WHERE c.id=ca.id_cliente
No me queda mucho más que contaros por aquí. Ya iremos haciendo otras entradas en las que contemos cosicas algo más concretas.
Y si tienes una base de datos y quieres optimizarla o algo para hacer que tu aplicación o página web sea más rápida y eficiente, y no sabes muy bien como hacerlo… Pregúntame que ya he pasado por unas cuantas optimizaciones…