
En MySQL 8.0.18 hay una nueva característica llamada Explicar Analizar cuando durante muchos años solo teníamos el tradicional Explain
. Sé que hay diferentes formatos, pero los que se basan en la misma información solo aparecen en un formato diferente con algunos detalles adicionales.
Mamá Explain Analyze
es un concepto diferente. De hecho, ejecutará la solicitud y medirá el tiempo de ejecución utilizando el nuevo ejecutor iterador para cada paso. Ese mismo tema merece su propia publicación de blog sobre cómo funciona el nuevo ejecutor iterativo, y también escribiré una publicación sobre eso. Pero si no puede esperar y quiere leer, aquí hay algunos enlaces para obtener información adicional: preguntas de análisis del ejecutor del iterador, Dibujo del iterador de volcán, y Semiunión de iterador de volcán.
En este post, nos centraremos en lo que Explain Analyze
nos puede dar.
Como siempre, comencemos con algunas pruebas. Tengo mi servidor de prueba con una tabla sbtest1:
CREATE TABLE `sbtest1` (` id` int (11) NOT NULL, `k` int (11) NOT NULL DEFAULT ‘0’, ` c` char (120) NOT NULL DEFAULT », `pad` char (60) NO NULO PREDETERMINADO », CLAVE PRINCIPAL (`id`), CLAVE` idx3` (`k`)) MOTOR = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci
CREAR MESA `sbtest1` ( `identificación` En t(11) NO NULO, `k` En t(11) NO NULO DEFECTO ‘0’, `C` carbonizarse(120) NO NULO DEFECTO », `almohadilla` carbonizarse(60) NO NULO DEFECTO », LA OFICINA DEL ALCALDE LLAVE (`identificación`), LLAVE `idx3` (`k`) ) MOTOR=InnoDB DEFECTO CARÁCTER=utf8mb4 COTEJAR=utf8mb4_0900_ai_ci |
Hay casi 1 millón de filas en esto:
mysql> seleccionar número
de sbtest1; + ———- + | contar| + ———- + | 999999 | + ———- + 1 fila en conjunto (0.32 seg) mysql> selecciona el conteo sí sbprueba1;+ ———- + | contar | + ———- + | 999999 | + ———- + 1 póngase en fila |
en
colocar
(0,32segundo) explicación tradicional mysql> explicar el número de selecciónde sbtest1 donde k> 500000 G **************************** 1. fila *********** * *************** id: 1 select_type: tabla SIMPLE: sbtest1 particiones: NULL tipo: rango possible_keys: idx3 clave: idx3 key_len: 4 ref: NULL fila: 493204 filtrado: 100.00 Extra : Usando donde; Usando el índice 1 fila en conjunto, 1 advertencia (0.00 seg) mysql > explique selecciona el conteo sí sbtest1 donde k > 500000 G *************************** 1. póngase en fila*************************** identificación: 1seleccione tipo: SIMPLE mesa: sbtest1 particiones : NULOescribe : gama posibles_claves: idx3 llave :idx3 key_len: 4 si: NULO póngase en fila :493204 filtrado: 100.00 Extra: Usar donde ;Usar índice 1 póngase en fila en |
colocar 493204
,
1
advertencia
(0.00segundo) Con suerte, la mayoría de ustedes ya están familiarizados con este producto; podemos ver qué tabla e índice se usarán y también podemos ver que es una solicitud de intervalo y debe leerse aproximadamente Bien. Con InnoDB sabemos que es solo una estimación, no el número real. En el pasado, teníamos dos opciones: ejecutar la consulta y ver el número real, o ejecutar la consulta y verificar las estadísticas del gerente para obtener información aún más detallada.Ahora voy a ejecutar la consulta y ver el recuento real de filas:mysql> seleccionar númerode sbtest1 donde k> 500000 G **************************** 1. fila *********** * **************** cuenta : 625262 1 fila en conjunto (0,10 seg) mysql > Seleccione contar (*) sí sbtest1 donde k >500000GRAMO*************************** 1. póngase en fila *************************** contar ( *) :625262 |
1 625262
póngase en fila 0.10s
en Explain Analyze
colocar
(
0.10
segundo) Entonces la pregunta debe ser leída. remar y tomar . Vamos a ver. Explicar Analizar mysql> explicar analizar número de selección de sbtest1 donde k> 500000 G **************************** 1. fila *********** * *************** EXPLICAR: -> Agregado: cuenta (0) (tiempo actual = 178,225..178,225 filas = 1 bucles = 1) -> Filtro: (sbtest1.k> 500000 ) (costo = 98896,53 filas = 493204) (tiempo actual = 0,022..147,502 archivos = 625262 bucles = 1) -> Escaneo de rangos de índice en sbtest1 usando idx3 (costo = 98896,53 filas = 493204.08.04.04.021 fila real6) = 6252 bucles = 1) 1 fila en conjunto (0.18 seg) mysql > explique analizar selecciona el conteo sísbtest1 dondek >500000 G ***************************1. póngase en fila ***************************Explique: –>Agregar :contar(0) (Actualhora = 178.225..178.225 póngase en fila = 1bucles= 1)–> Filtrar: (sbtest1.k>500000) (costo=98896.53 póngase en fila=493204) (Actualhora = 0.022..147.502 póngase en fila = 625262 bucles = 1)–> Índicegamaevitar sobre sbtest1usaridx3 (costo=98896.53 póngase en fila=493204) (Actual hora = 0.021..96.488 póngase en fila = 625262 |
bucles tree
=
1)
Index range scan on sbtest1 using idx3
cost=98896.53 rows=493204
1 Explain
póngase en fila
actual time=0.021..96.488 rows=625262 loops=1
en
- colocar (0.18
- segundo) Siempre usas el
- formateado y me tomó un tiempo entender realmente lo que significa toda esta información. Desafortunadamente, la página de manual realmente no lo explica. Déjame tratar de llenar los espacios en blanco: – esta parte es bastante trivial, dice que usará un escaneo gamma en la tabla sbtest1 y usará el índice idx3.
- – este es el costo y el mismo número de filas que el tradicional nos lo da.
: 0.021– Tiempo para volver a la primera fila (Init + primera lectura) en milisegundos.
96,488
– Tiempo para devolver todas las filas (Init + todas las llamadas de lectura) en milisegundos. 178ms
fila = 625262 1 row in set (0.18 sec)
– El número de fila devuelto por este iterador. 0.18s
Finalmente, es el número exacto. 0.10s
bucles = 1
– El número de bucles (número de llamadas Init).
La fuente de esta información está aquí:
Implementar EXPLICAR ANÁLISIS
.
Podemos ver toda esta información con cada paso, lo que nos brinda una gran ayuda e información para la optimización de consultas.
Pero es importante notar en el último paso qué hora es
y también informes. Así que dice que esta pregunta se hace cargo ! Pero la solicitud original solo despegó. El manual dice: Esto, por supuesto, tiene algunos gastos generales, pero parece que esto es solo alrededor del 5-6% para una aplicación instrumentada (completamente gratis para una aplicación no tripulada). Pero con esta pregunta tan simple, la sobrecarga ya es del 80%, por lo que realmente no podemos confiar en esos números. Veamos otra pregunta que lleva más tiempo y veamos cómo funciona esta diferencia: mysql> seleccionar número desde sbtest1 t1 izquierda unirse a sbtest1 t2 en t1.k = t2.k; + ———- + | contar | + ———- + | 77902613 | + ———- + 1 fila en conjunto (15.42 seg)mysql> selecciona el conteo sí sbtest1 t1 deja que se una sbtest1 t2 sobre t1.k = t2.k; + ———- + | contar |
| + ———- + | 77902613| + ———- + 1 póngase en fila en colocar (15.42 segundo) mysql> explicar analizar número de selecciónda sbtest1 t1 dejó unirse a sbtest1 t2 en t1.k = t2.k G ******************************* 1. fila ** * ************************** EXPLICADO: -> Agregado: cuenta (0) (hora actual = 26501.232..26501.233 archivo = 1 bucles = 1) -> Unión izquierda anidada de bucle (costo = 810799,35 filas = 4550475) (hora actual = 0,036..22572.530 filas = 77902616 bucles = 1) -> Escaneo de índice en t1 usando idx3 (costo = 108280.564..22572.530 filas = 0.58640.60.60.176,645 filas = 999999 bucles = 1) -> Búsqueda de índice en t2 con idx3 (k = t1.k) (costo = 0.25 filas = 5) (tiempo actual = 0.001..0.017 archivos = 78 bucles = 999999 ) Juego de 1 fila (26,50 seg)mysql > explique analizar selecciona el conteo sísbtest1 t1deja que se una sbtest1t2 sobre t1.k=t2.kG ***************************1.póngase en fila ***************************Explique: –> Agregar : contar (0)(Actualhora =26501.232..26501.233póngase en fila = 1bucles= 1)–> Anidadociclodeja que se una (costo= 810799.35 póngase en fila = 4550475) (Actual hora =0.036..22572.530póngase en fila =77902616bucles = 1)–> Índiceevitarsobre t1usaridx3 (costo= 108280.56 póngase en fila = 986408) (Actual hora =0.026..176.645póngase en fila =999999bucles =1)– > ÍndiceBuscandosobre t2usaridx3 (k=t1.k) (costo = 0.25 póngase en fila = 5) (Actual |
hora
= Explain Analyze
0,001 … 0,017
póngase en fila Explain Analyze
=
78
bucles
=999999) 1 póngase en filaen colocar (26.50 segundo) Informa que la demanda es un 60% más lenta que en la vida real. Solo por curiosidad probé con un procedimiento almacenado, pero no funcionó. Una de las tareas más dolorosas es analizar y optimizar un procedimiento almacenado porque MySQL no registra las solicitudes individuales de un procedimiento y es difícil ver realmente lo que sucede debajo del capó. (En Percona Server hay log_slow_sp_statements que le permiten registrar consultas individuales en un registro de consultas lentas). Me encantaría ver sirealice el procedimiento y luego muestre el plan de ejecución actual en un formato de árbol. Pero tal vez creo en un mundo perfecto y soy demasiado ingenuo. También noté un comportamiento interesante:mysql> explicar analizar número de selección de sbtest1 G ***************************** 1. fila ************** *** ********** EXPLICAR: -> Cuenta y fila en sbtest1 1 fila en conjunto (0.13 seg) mysql > explique analizar selecciona el conteo sí sbtest1G *************************** |
1.
póngase en fila
*************************** Explain Analyze
Explique
: -> Cuentas de fila en sbtest1 1 fila en conjunto (0.13 seg) Si no hay ninguna condición donde, o un grupo para, o cualquier otra cosa y solo una simple solicitud de cuentas, no nos da tiempo para qué paso o fila fue leído o qué índice se utilizó. Creo que esto es un poco minimalista y sería bueno ver alguna información básica. Conclusión Creo que es un gran paso en la dirección correcta, y estoy emocionado de ver si obtiene aún más funciones en el futuro, pero debería informar tiempos de ejecución más realistas.