Explain MySQL o cómo optimiza SQL
Written by Sergi on 3 Septiembre 2008 – 17:53 pm -Hoy he tenido una interesante conversación con Marc Lladó i con José Mª Rodríguez (álias UTF8 ;-)) sobre SQL y la optimización sql del mismo (en un entorno MySQL).
Al final se puede resumir que EXPLAIN MySQL es una herramienta indispensable (no la única) a la hora de realizar tareas de otpimización sql.
Explain MySQL no es más que una manera de mostrar como MySQL procesa las sentencias SQL mediante sus índices y uniones. El uso de Explain MySQL permite ayudar a los DBAs, en una primera instancia, a mejor el diseño de base de datos agregando índices y permitiendo una selección de consultas más óptimas.
Lo único que debemos hacer para hacer uso de Explain MySQL es anteponer “Explain” a la SQL deseada.
EXPLAIN SELECT * FROM `localidades` WHERE id =1
Ejecutando esta SQL, MySQL nos indica como la está procesando y nos mostrará un listado con información sobre índices, tablas, resultados, etc.
En el resultado de explain de mysql visualizaremos una tabla con 10 columnas de información para cada tabla implicada
- type: Esta columna indica el tipo de unión que se está usando (de más a menos óptimo).
- const: Es la más óptima y se dá cuando la tabla tiene como máximo una fila que coincide. Como solo hay una fila coincidente, MySQL la considerará como constante por el optimizador.
- eq_ref: Una fila será leída de la tabla A por cada combinación de fila de la tabla B. Este tipo es usada cuando todas las partes de un índice son usados para la consulta y el índice es UNIQUE o PRIMARY
- ref: Todas las filas con valores en el índice que coincidan serán leídos desde esta tabla por cada combinación de filas de las tablas previas. Si la clave que es usada coincide sólo con pocas filas, esta unión es buena.
- range: Sólo serán recuperadas las filas que estén en un rango dado, usando un índice para seleccionar las filas. La columna key indica que índice se usará, y el valor key_len contiene la parte más grande de la clave que fue usada. La columna ref será NULL para este tipo.
- index: Este es el mismo que ALL, excepto que sólo el índice es escaneado. Este es usualmente más rápido que ALL, ya que el índice es usualmente de menor tamaño que la tabla completa.
- ALL: Realiza un escaneo completo de tabla por cada combinación de filas de las tablas previas. Este caso es el peor de todos.
- possible_keys: Esta columna indica los posibles índices a utilizar en la consulta
- key: Esta columna indica el indice que MySQL actualmente está usando. Esta columna es NULL si no se ha elegido ninguno. Es interesante saber que podemos forzar a MySQL a usarlo (y también a ignorarlo) mediante el uso de FORCE INDEX, USE INDEX o IGNORE INDEX
- key_len: El tamaño del índice usado. A menor valor mejor.
- ref: La columna ref muestra que columna o constante es usada junto a la key para seleccionar las columnas de la tabla
- rows: Indica el número de columnas que MySQL cree necesario examinar para ejecutar la SQL.
- extra: Indica información adicional de como MySQL ha resuelto la SQL y hay que prestar atención si aparece USING FILESORT o USING TEMPORARY. En el primer caso, indica que MySQL debe hacer un paso extra para recuperar la información. En el segundo, MySQL necesita generar una tabla extra para mantener la información y después mostrarla y es típico al usar GROUP BY u ORDER BY.
En ocasiones, MySQL puede mostrar ALL en la columna type cuando:
- La tabla es tan pequeña que MySQL ve más rapido hacer un escaneo completo de la tabla.
- No hay restricciones usando las cláusulas ON o WHERE.
- Se compara columnas indexadas con valores cosntantes
- Las claves utilizadas devuelven muchos registros que coinciden con el valor.
Aún así, hay que decir que éste no es el único método de optimización SQL, aunque es uno bueno.
Para más información visita la referncia
Tags: mysql, mysql explain, optimizacion, optimizar, SQL
Posted in General, SQL |


Septiembre 4th, 2008 at 13:04 pm
Bravo Sergi,
buena este articulo sobre el EXPLAIN, la usaré como referencia cuando contemos con millones sinó trillones de registros diarios
Hasta el momento estoy usando una herramienta para generar datos de prueba para nuestra BD. Se llama spawner, se encuentra en su versión 0.1.4.0. Se que como esta herramienta deben haber varias pero esta es GPL y a mí me ha dado buenos resultados.
Jejeje te dejo de recuerdo un poco de [SPAM] esta es la URL de spawner en sourceforge.
https://sourceforge.net/projects/spawner
Un saludo! te seguiré leyendo
Septiembre 23rd, 2008 at 21:23 pm
[...] Un detalle que me ha gustado del Navicat Lite es que cuando ejecutas una query, puedes acceder a los resultados y al EXPLAIN. [...]
Septiembre 26th, 2008 at 18:14 pm
Marc, no se necesita hablar de millones de registros diarios. Con unos miles se pone lerdo, ni hablar de GROUP BY, ORDER BY y demás.
Diciembre 12th, 2008 at 10:25 am
[...] Explain MySQL o cómo optimiza SQLwww.sergiquinonero.net/explain-mysql-o-como-optimiza-sql.html por esmiz hace pocos segundos [...]
Enero 6th, 2009 at 20:57 pm
como puedo optimizar estas consultas:
SELECT CLI_NOMB
FROM CLIENTE
WHERE CLI_ID = 100
y esta:
SELECT CLI_NOMB
FROM CLIENTE, EMBARQUE
WHERE CLI_ID = EMB_ID_CLI
AND EMB_DESTINO = ’Rancagua’
gracias
Enero 6th, 2009 at 21:04 pm
La optimización de la primera consulta sería de caracter interna, por ejemplo, creando un índice en el campo donde realizas el filtrado (en este caso CLI_ID).
Sobre la segunda… no utilizar esa sintaxis. Al indicar las tablas en el from separadas por comas, estas haciendo que el motor de MySQL trabaje demasiado, dado que tiene que hacer un producto cartesiano de ambas tablas, y a posterior, el filtrado. Podrias utilizar el uso de JOINs. Se podrian realizar “otras” optimizaciones; evitar el uso de string en los filtros por ejemplo.
Enero 8th, 2009 at 14:26 pm
5, Resp:
En el primer caso no deberia ser necesaria optimizacion si CLI_ID es la PK de la tabla, que por diseño debería ser, de lo contrario es probable que el modelo de datos este mal implementado XD. En el segundo caso, EMB_ID_CLI debe ser parte de la clave de EMBARQUE o estar en un indice. Respecto del uso de texto en el filtro, lo ideal es incluir en el “where” campos en algun indice o alguna PK. Si bien se puede usar textos como campos de indice, no se recomienda para no hacer crecer tanto los indices, pero si es un campo con un largo limitado y razonable, debiera estar en un indice, y si no, al menos intenta que sea uno de los ultimos campos en ser evaluados
Enero 8th, 2009 at 14:58 pm
bueno, depende del diseño de base de datos. Al no indicar como es la estructura de las tablas, puede haber varias formas de optimizarla.
Enero 8th, 2009 at 18:48 pm
Gracias a todos por las aclaraciones, mi resolucion a estos dos ejercicios es:
SELECT CLI_ID , CLI_NOMB
FROM CLIENTE
WHERE CLI_ID = 100
y al otro:
SELECT CLI_ID , CLI_NOMB
FROM (Select cli_id, emb_id
From cliente join embarque
on CLI_ID = EMB_ID_CLI
where emb_destino= ‘rancagua`
las tablas son asi:
CLIENTE{CLI ID, CLI NOMB, CLI RENTA ANUAL, CLI TIPO}
EMBARQUE{EMB ID, EMB ID CLI, EMB PESO, EMB ID CAMION, EMB DESTINO, EMB FECHA}
Alguien me puede ayudar pasandome ejercicios resueltos de optimizacion, procedimientos y triggers?? por favor.