Aunque siempre deseamos un mayor rendimiento y más y mejores características para MySQL, estas no pueden aparecer “sin más” de una versión a otra, requiriendo profundos cambios en la arquitectura y muchas líneas de código. Sin embargo, a veces hay pequeños cambios y arreglos que podrían implementarse por un becario o contribuidor externo, principalmente en la capa SQL, que podrían hacer el ecosistema de MySQL más amigable para novatos y no expertos. Hacer que un programa sea más fácil de usar es muchas veces pasado de largo, pero es increíblemente importante -no todo el mundo usando MySQL es un administrador de bases de datos, y cuanta más gente lo adopte, más gente podrá vivir de él, tanto sus desarrolladores originales como proveedores externos.
Esta es mi propia lista de arreglos para los mensajes de EXPLAIN. Si ya eres un usuario experimentado de MySQL probablemente ya conozcas su sugnificado, pero eso no resuelve el problema para los principiantes. La razón por la que estoy escribiendo este post es para recoger opiniones sobre si os parecen importantes o no, y si mi manera de resolverlos parece razonable para poder enviarlas como “feature requests”.
Mensajes de EXPLAIN
Como instructor MySQL, el caso siguiente me ocurre mucho con nuevos estudiantes. Comienza con un comando como el siguiente:
mysql> EXPLAIN SELECT b, c FROM test\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: index possible_keys: NULL key: b_c key_len: 10 ref: NULL rows: 4 Extra: Using index 1 row in set (0.00 sec)
Entonces, “Using index
” significa que se está usando un índice, ¿verdad? No, en este caso type: index
nos indica que se está usando un índice para escanear o acceder a las filas (porque no es un type: ALL
– aunque podríamos obtener un full row scan e usar el índice para ordenar o agruparlas). El Extra: Using index
indica que el índice se usa para devolver los datos, sin necesidad de leer la fila completa. A esto, por lo que yo sé, se le refiere comúnmente como Covering index. Y eso es exactamente lo que me gustaría ver:
mysql> EXPLAIN SELECT b, c FROM test\G -- salida editada *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: index possible_keys: NULL key: b_c key_len: 10 ref: NULL rows: 4 Extra: Using covering index 1 row in set (0.00 sec)
o alternativamente:
Extra: Covering index
Otro malentendido común: Using filesort
:
mysql> EXPLAIN SELECT * FROM test ORDER BY length(b)\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 4 Extra: Using filesort 1 row in set (0.00 sec)
A este nivel no me interesa si estoy usando filesort como algoritmo y -si no me equivoco- desde 5.6 también se puede usar una cola de prioridad como algoritmo de ordenamiento si el numero de elementos es pequeño. Además, el “file” de la palabra filesort puede llevar la confusión de que esto requiera una tabla temporal en disco. No tengo una alternativa perfecta (por favor, dadme ideas), pero algo como lo siguiente sería más claro:
mysql> EXPLAIN SELECT * FROM test ORDER BY length(b)\G -- salida editada *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 4 Extra: Additional sort phase 1 row in set (0.00 sec)
o alternativamente:
Extra: Not using index for order-by
Otro ejemplo sería:
mysql> EXPLAIN SELECT a FROM test WHERE b > 3 and c = 3\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: range possible_keys: b_c key: b_c key_len: 5 ref: NULL rows: 1 Extra: Using index condition 1 row in set (0.00 sec)
Entiendo que quizá los desarrolladores no quisieron confundirnos con la técnica pushed condition de NDB, pero esta salida lleva al equívoco también. Literalmente significa que “la condición del índice se está usando”, en vez de que se está usando “ICP. ¿Qué os parece:
mysql> EXPLAIN SELECT a FROM test WHERE b > 3 and c = 3\G -- salida editada *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: range possible_keys: b_c key: b_c key_len: 5 ref: NULL rows: 1 Extra: Using index condition pushdown 1 row in set (0.00 sec)
Hay muchas otras expresiones, pero esas son las que más me molestas en términos de confusión de estudiantes.
¿Estás de acuerdo conmigo? ¿Romperían estos cambios aplicaciones que parsean la salida de EXPLAIN? ¿Qué otras pequeñas cosas cambiarías en la salida de MySQL or sus mensajes de error? Me gustaría oír especialmente a los que están empezando con MySQL y a las personas que vengan de otras bases de datos, ya que cuanto más lo usamos, más nos acostumbramos a los MySQLismos.