El proceso específico de MYSQL ejecutando una instrucción SELECT

CSDN de repente tuvo una convulsión ayer. Borré todo el artículo con ctrl+z y no pude restaurarlo. Perdí la cabeza y no quería escribirlo. Pero esta parte es muy importante, vamos a escribirla

diagrama de flujo 

Hay un total de dos capas de estructura Motor de almacenamiento de capa de servidor

  • La capa Servidor se encarga de establecer conexiones, analizar y ejecutar SQL . La mayoría de los módulos funcionales básicos de MySQL se implementan aquí, incluidos principalmente conectores, cachés de consultas, analizadores, preprocesadores, optimizadores, ejecutores, etc. Además, todas las funciones integradas (como la fecha, la hora, las funciones matemáticas y de cifrado, etc.) y todas las funciones del motor de almacenamiento cruzado (como los procedimientos almacenados, los disparadores, las vistas, etc.) se implementan en la capa del servidor.
  • La capa del motor de almacenamiento es responsable del almacenamiento y la recuperación de datos . Admite varios motores de almacenamiento, como InnoDB, MyISAM y Memory, y diferentes motores de almacenamiento comparten una capa de servidor. Ahora, el motor de almacenamiento más utilizado es InnoDB A partir de MySQL 5.5, InnoDB se ha convertido en el motor de almacenamiento predeterminado de MySQL. La estructura de datos de índice que solemos decir está implementada por la capa del motor de almacenamiento, y los tipos de índice admitidos por diferentes motores de almacenamiento son diferentes. Por ejemplo, el tipo de índice admitido por InnoDB es el árbol B+, que se usa de forma predeterminada, es decir , se crea en la tabla de datos. El índice de clave principal y el índice secundario del índice de árbol B + de uso predeterminado.

Paso 1: Conector 

Es el proceso de conexión del usuario a MYSQL, habrá tres apretones de manos y cuatro manos saludadas, porque la conexión se transmite en base al protocolo TCP.

# -h 指定 MySQL 服务得 IP 地址,如果是连接本地的 MySQL服务,可以不用这个参数;
# -u 指定用户名,管理员角色名为 root;
# -p 指定密码,如果命令行中不填写密码(为了密码安全,建议不要在命令行写密码),就需要在交互对话里面输入密码
mysql -h$ip -u$user -p

 Si el servicio MySQL se ejecuta normalmente, después de que se complete el establecimiento de la conexión TCP, el conector comenzará a verificar su nombre de usuario y contraseña. Si el nombre de usuario o la contraseña son incorrectos, recibirá un error de "Acceso denegado para el usuario". , y luego el programa cliente finaliza implement.

Si no hay problema con la contraseña del usuario, el conector obtendrá los permisos del usuario y los guardará. Cualquier operación posterior del usuario en esta conexión se juzgará en función de los permisos leídos al comienzo de la conexión.

Por lo tanto, si un usuario ya ha establecido una conexión, incluso si el administrador modifica los permisos del usuario a mitad de camino, no afectará los permisos de la conexión existente. Una vez completada la modificación, solo las nuevas conexiones utilizarán la nueva configuración de permisos.

capaz de pasar

 SHOW PROCESSLIST;

Compruebe cuántos usuarios están conectados a MYSQL

Por ejemplo, como se muestra en la figura anterior, hay dos usuarios cuyo nombre de usuario es raíz conectado al servicio MySQL, y el estado de la columna Comando del usuario cuya identificación es 6 es , lo que significa que el usuario no ha ejecutado  Sleep ningún comandos después de conectarse al servicio MySQL. , lo que significa que se trata de una conexión inactiva, y el tiempo de inactividad es de 736 segundos (columna Tiempo).

¿La conexión inactiva estará ocupada todo el tiempo?

Por supuesto que no, MySQL define el tiempo máximo de inactividad de las conexiones inactivas,  wait_timeout controlado por parámetros, el valor predeterminado es de 8 horas (28880 segundos), si la conexión inactiva supera este tiempo, el conector lo desconectará automáticamente.

mysql> show variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+
1 row in set (0.00 sec)

Por supuesto, también podemos desconectar manualmente la conexión inactiva, usando el comando kill connection + id.

La diferencia entre enlaces largos y enlaces cortos

短连接
连接 mysql 服务(TCP 三次握手)
执行sql
断开 mysql 服务(TCP 四次挥手)

// 长连接
连接 mysql 服务(TCP 三次握手)
执行sql
执行sql
执行sql
....
断开 mysql 服务(TCP 四次挥手)

Entonces, solo hay una instrucción SQL para una conexión corta y varias instrucciones SQL para una conexión larga.

Para la misma tarea, usamos conexiones largas para guardar múltiples conexiones y desconexión de MYSQL que conexiones cortas.

¿Pero no hay inconveniente en la conexión larga?

MySQL usa temporalmente la memoria para administrar los objetos de conexión durante la ejecución de la consulta, y estos recursos de objetos de conexión solo se liberarán cuando se desconecte la conexión. Si hay muchas conexiones largas, el servicio MySQL ocupará demasiada memoria y el sistema puede eliminarlo por la fuerza, lo que hará que el servicio MySQL se reinicie de manera anormal.

Cómo resolvemos este problema

¿No te desconectas?

1. Desconexión manual periódica

2. El cliente restablece activamente la conexión . MySQL versión 5.7 implementa  mysql_reset_connection() la interfaz de función. Tenga en cuenta que esta es una función de interfaz en lugar de un comando. Luego, cuando el cliente realiza una operación grande, llame a la función mysql_reset_connection en el código para restablecer la conexión y liberar la memoria. Este proceso no requiere reconexión ni reautenticación, pero restaurará la conexión al estado recién creado.

Cada vez que aprendo los principios subyacentes de XX, siento que la operación subyacente lleva el peso para mí.

Paso 2: consulta el caché 

Una vez que finaliza el trabajo de conexión, el cliente puede enviar declaraciones SQL a MYSQL. Primero analizará el primer campo de la declaración para ver qué declaración es. Si es una declaración SELECT, irá a la caché de consultas (Query Cache ) para buscar los datos almacenados en caché para ver si este comando se ha ejecutado antes. El caché de consulta se almacena en la memoria en forma de clave-valor. La clave es la declaración de consulta SQL y el valor es el resultado de la consulta de la instrucción SQL.

Si la instrucción de consulta llega a la memoria caché de consultas, el valor se devolverá directamente al cliente. Si la declaración de consulta no llega a la caché de consultas, continuará ejecutándose.Después de la ejecución, el resultado de la consulta se almacenará en la caché de consultas.

Mirándolo de esta manera, es increíble. ¿No es este caché de consultas como una matriz dp que se puede optimizar y ejecutar en grandes cantidades?

De hecho, no es porque el caché de esta tabla se borrará cada vez que se actualicen los datos para esta tabla.... Ah, es decir, si no se pueden encontrar los datos actualizados, solo se puede consultar una vez sin actualizando datos 

"Entonces, ¿por qué lo verifico? Solo saco el último resultado de la consulta y lo uso.

Muy bien, MYSQL también lo cree, por lo que MYSQL8.0 elimina directamente esta cosa

Paso 3: analizar SQL

Lo primero: análisis léxico, MYSQL analizará las palabras clave en su declaración SQL y luego formará un árbol de sintaxis SQL para que los módulos posteriores puedan obtener tipos SQL, nombres de tablas, nombres de campos, condiciones de ubicación, etc. (Dé a MYSQL un análisis de oraciones largo y difícil)

Lo segundo: el análisis sintáctico es para ver si hay errores gramaticales

El error gramatical está en negrita aquí. Los campos, las tablas y los datos no existen, por lo que no es un error gramatical.

Al igual que la verificación de código de bytes de verificación de metadatos en JVM

Paso 4: Ejecutar SQL

Correspondientes a los cuatro bloques de la figura.

  • La etapa de preparación, es decir, la etapa de preprocesamiento;
  • La etapa de optimización es la etapa de optimización;
  • La fase de ejecución, es decir, la fase de ejecución;

etapa de preprocesamiento 

 Eso debe estar en el preprocesador.En lo que respecta a SELECT, el preprocesamiento hace dos cosas

1. Comprobar si los campos, tablas y otros datos existen

2. Reemplace * con todas las columnas

etapa de optimización

Correspondiente, por supuesto, es el optimizador

Sabemos que es muy problemático cuando MYSQL ejecuta una declaración. Es necesario juzgar el índice y la longitud. Este paso es determinar un plan de ejecución específico.

Podemos agregar un comando al principio de la declaración de consulta  explain , de modo que se emita el plan de ejecución de esta declaración SQL, y luego la clave en el plan de ejecución indica qué índice se usa durante la ejecución. Si el parámetro clave es nulo, significa que no se usa Index significa que se usa la consulta de tabla completa más ineficiente

Específicamente, ¿qué solución elegirá el optimizador?

SELECT id FROM product WHERE id > 1  AND name LIKE 'i%';

El resultado de esta declaración de consulta puede usar tanto el índice de clave principal como el índice ordinario, pero la eficiencia de ejecución será diferente. En este momento, se requiere que el optimizador decida qué índice usar.

El índice de cobertura se usa aquí, es decir , la información en estos dos índices es suficiente para cumplir con la solicitud de consulta cuando se usan estos dos índices al mismo tiempo , y no hay necesidad de volver al índice de clave principal para obtener datos. ( El costo de consultar el árbol B+ del índice de clave principal será mayor que el costo de consultar el B+ del índice secundario. Según la consideración del costo de la consulta, el optimizador elegirá el índice ordinario con un costo de consulta bajo) .

¿Cuál es el proceso?Primero, encuentre los datos coincidentes en el índice secundario (nombre), luego los datos almacenados en el índice secundario son la identificación de la clave principal, y luego registre los datos con id> 1, por lo que no hay necesidad de ir al índice de clave principal, y el resultado se mostrará directamente.

fase de ejecución 

Fase de ejecución, que debe ser el ejecutor

Después de pasar por el optimizador, tenemos el plan de ejecución, ahora es el momento de ejecutar formalmente el SQL

Durante el proceso de ejecución, el ejecutor interactuará con el motor de almacenamiento y la interacción es en unidades de registros.

Hay tres métodos de ejecución en total:

  • consulta de índice de clave principal
  • exploración completa de la tabla
  • empuje hacia abajo del índice

consulta de índice de clave principal

Desde la perspectiva del análisis del lenguaje, debe estar consultando a través del índice de clave principal, ¿verdad (?)

Veamos esta línea de código.

select * from product where id = 1;

 En primer lugar, id es la clave principal, debe ser 1 y esta condición de filtro es equivalente, por lo que solo se consultará una vez.

El ejecutor consulta por primera vez y llama a la función a la que apunta el puntero de función read_first_record

Este puntero de función apunta a la interfaz de la consulta de índice del motor InnoDB (el parámetro del optimizador es const, y el motor de almacenamiento puede elegir el modo de ejecución correspondiente solo con este parámetro), y la condición se le da al motor de almacenamiento, para que el El motor de almacenamiento localiza el primer registro que cumple  id = 1 la condición . Luego, el motor de almacenamiento encuentra los datos con id 1 a través del índice de clave principal (árbol b+)

Sentencia 1: Si el registro no existe, se informará al ejecutor de un error de que no se encuentra el registro y luego finaliza la consulta. Si el registro existe, lo devuelve al ejecutor;

Entonces si existe, juez 2

Comprobar si se cumple la condición del filtro, si se cumple se envía al cliente, si no se salta el registro.

El proceso de consulta del ejecutor es un bucle while, por lo que se verificará nuevamente, pero esta vez porque no es la primera consulta, por lo que esta vez llamará a la función a la que apunta el puntero de la función read_record (diferente del anterior read_first_record ), porque el optimizador El tipo de acceso seleccionado es const (aparece de nuevo el parámetro mencionado anteriormente), y este puntero de función se apunta como una función que siempre devuelve -1, por lo que cuando se llama a esta función, el ejecutor sale del bucle, eso es, finaliza la consulta

exploración completa de la tabla

select * from product where name = 'iphone';

El primer paso permanece sin cambios, o llama a la función a la que apunta el puntero de la función read_first_record, pero esta vez porque es un escaneo completo de la tabla (el parámetro del optimizador es all)

Paso 2 Comience a leer desde el primer registro para ver si cumple con la condición DONDE (nombre = iPhone) De lo contrario, omita y envíe este registro al cliente

El proceso de consulta del ejecutor es un bucle while, por lo que se verificará nuevamente y se llamará a la función a la que apunta el puntero de la función read_record, porque el tipo de acceso seleccionado por el optimizador es all, y el puntero de la función read_record aún apunta a la interfaz del escaneo completo del motor InnoDB, luego solicite a la capa del motor de almacenamiento que continúe leyendo el siguiente registro del registro anterior. Después de que el motor de almacenamiento obtenga el siguiente registro, lo devuelve al ejecutor (capa del servidor), y el ejecutor continúa juzgando las condiciones, si no cumple con las condiciones de la consulta, salta De lo contrario, envía el registro al cliente, repite el proceso anterior hasta que el motor de almacenamiento lea todos los registros en la tabla, y luego devuelve la lectura información al ejecutor (capa del servidor); el ejecutor recibe el informe del motor de almacenamiento Después de consultar la información, salga del ciclo y deje de consultar. 

empuje hacia abajo del índice

Es una estrategia de optimización de consultas introducida por MySQL 5.6

select * from t_user  where age > 20 and reward = 100000

Supongamos que creamos índices por edad y recompensa.

Cuando el índice conjunto encuentra una consulta de rango (>, <), dejará de coincidir, es decir, el  campo de edad puede usar el índice conjunto, pero el campo de recompensa no puede usar el índice (solo recuérdelo, y la parte no válida del el índice puede actualizarse más tarde)

Si no se utiliza la inserción de índice

El primer paso sigue siendo: la capa del servidor llama al motor de almacenamiento para encontrar el primer registro que satisfaga la edad> 20

Paso 2: el motor de almacenamiento ubica rápidamente este registro de acuerdo con el árbol B+ del índice secundario, obtiene el valor de la clave principal y luego devuelve el registro completo a la capa del servidor.

tercer paso:

Luego, el servidor juzga si la recompensa es igual a 100000. Si cumple con el requisito, devuélvelo al usuario. Si no cumple con el requisito, ignórelo.

Paso 4: Luego tome el siguiente registro (no es necesario volver a ubicar los registros, los registros están conectados por una lista vinculada) Después de que el índice secundario localice el registro, el motor de almacenamiento obtiene el valor de la clave principal y luego regresa a la tabla para obtener todos los datos de registro para juzgar si se ajustan a

Luego haga un bucle en tres o cuatro pasos hasta que se consulten los registros de edad> 20

Cuando no hay inserción de índice, cada vez que se consulta un registro de índice secundario, debe devolverse a la tabla, y luego el registro se devuelve al servidor, y luego el servidor juzga si la recompensa del registro es igual a 100000

¿Qué pasa cuando hay una caída del índice?

La capa del servidor primero llama a la interfaz del motor de almacenamiento para ubicar el primer registro de índice secundario que cumple con las condiciones de la consulta, es decir, ubica el primer registro con antigüedad > 20;

Después de que el motor de almacenamiento localiza el índice secundario, no ejecuta la operación de devolución de la tabla, pero primero juzga si la condición (si la recompensa es igual a 100000) de la columna (columna de recompensa) contenida en el índice es verdadera. Si la condición no es verdadera, omita el índice secundario directamente. Si está establecido, ejecute la operación de volver a la tabla y devuelva el registro completo a la capa del Servidor.

La capa del servidor está evaluando si otras condiciones de consulta (esta consulta no tiene otras condiciones) son verdaderas (¿por qué el motor de almacenamiento solo puede evaluar la condición de recompensa? Porque aunque no usa el índice conjunto, todavía hay algunos datos indexados en el índice conjunto, es muy conveniente encontrar la recompensa por id (correspondencia uno a uno), si está establecida, se enviará al cliente, de lo contrario, omita el registro y luego solicite al motor de almacenamiento el siguiente registro. Esto sigue y sigue hasta que el motor de almacenamiento ha leído todos los registros de la tabla.

Es equivalente a externalizar la cuestión de juzgar si la recompensa es igual a 100.000 para el motor de almacenamiento.

La inserción del índice puede reducir la operación de retorno de la tabla del índice secundario durante la consulta y mejorar la eficiencia de la consulta, ya que transfiere la parte de la capa del servidor a la capa del motor de almacenamiento para su procesamiento.

Supongo que te gusta

Origin blog.csdn.net/chara9885/article/details/131521230
Recomendado
Clasificación