Proceso de ejecución detallado de la declaración de unión de MySQL

antecedentes

Hoy, optimicé una declaración para la verificación de asociación de unión, y la declaración que debe optimizarse para la unión, luego debemos comprender uno de sus procesos de ejecución. Como dice el refrán, conócete a ti mismo y al enemigo, ¡gana todas las batallas! !

unirse al algoritmo de consulta

1. Unión de bucle anidado simple (combinación de bucle anidado simple)

  • El proceso de consulta del algoritmo de bucle anidado simple es una consulta anidada. Esta declaración de consulta asociada no puede determinar cuál es la tabla principal al principio, porque si usa join, el optimizador mysql elegirá el índice en sí mismo (este también es el caso cuando el DBA no permite Uno de los motivos de la consulta de combinación). Si los campos ayb no están indexados, aparecerá esta consulta de algoritmo.
  • Proceso de consulta: primero encuentre el campo calificado a en la tabla t1 y luego recorra la tabla t2 para recorrer el ciclo. (Pero este algoritmo no se usa en mysql)
    Inserte la descripción de la imagen aquí
select * from  t1 join t2  on t1.a = t2.b

2. Unión de bucle anidado de índice (Unión de bucle anidado de índice)

  • El uso de straight_join significa que señalamos claramente que t1 es la mesa conductora y t2 es la mesa conducida.
  • Proceso de consulta: tome una parte de los datos de t1 y luego use el índice b para hacer coincidir con t2. Si b es un índice de cobertura y contiene los campos que necesitamos, entonces no es necesario realizar una consulta de regreso a la tabla, pero si estos campos no contienen Todo, luego debe realizar una consulta de regreso a la tabla nuevamente. Si los campos de la tabla inicial están indexados, ¿el algoritmo de consulta es el mismo? De hecho, lo mismo es cierto excepto que la mesa conductora primero verifica el índice y luego escanea la mesa conducida.
  • Entonces, ¿cómo deberíamos elegir la mesa principal en las dos situaciones anteriores? ¿Qué pasa con la tabla indexada pero no la tabla indexada? Personalmente, creo que esto no es necesariamente cierto. Si una tabla solo se usa como una condición de consulta y no como un campo de tabla y esta tabla tiene un índice del campo asociado
    Inserte la descripción de la imagen aquí
select * from  t1 straight_join t2  on t1.a = t2.b(t2中的表字段有索引)

3. Bloque de unión de bucle anidado (unión de bucle anidado de bloque de caché)

  • El algoritmo Simple Nested-Loop Join que se acaba de mencionar no se usa en MySQl. Si los campos asociados de las dos tablas no están indexados, ¿cómo lo maneja mysql? Eso es para usar el algoritmo Block Nested-Loop Join

  • Proceso de consulta: lee los datos de la tabla t1 en la memoria de subprocesos join_buffer, porque escribimos select * en esta declaración, colocamos toda la tabla t1 en la memoria; escanea la tabla t2 y saca cada fila de la tabla t2 , Compare con los datos de join_buffer y devuelva aquellos que cumplen las condiciones de combinación como parte del conjunto de resultados.
    Inserte la descripción de la imagen aquí

  • Pero el tamaño de este joinbuffer es limitado. Cuando el joinbuffer está lleno y la consulta no se puede completar a la vez, la estrategia es realizar múltiples consultas

    1. Escanee la tabla t1, lea las filas de datos secuencialmente y colóquelas en join_buffer Después de poner el join_buffer en la fila 88, continúe con el paso 2;
    2. Escanee la tabla t2, saque cada fila en t2, compare con los datos en join_buffer y regrese como parte del conjunto de resultados si se cumplen las condiciones de unión; borre join_buffer;
    3. Continúe escaneando la tabla t1, lea secuencialmente las últimas 12 filas de datos en join_buffer y continúe con el paso 2.
    4. De esta manera, el ciclo procede a obtener el resultado final establecido para regresar.

4. Acceso a claves por lotes

  • El algoritmo NLJ primero lee una fila de datos de la tabla conducida y luego va a la tabla conducida para hacer coincidir los datos. Pero si la cantidad de datos en las dos tablas es demasiado grande, se producirán problemas de rendimiento. Hay una optimización MRR en la optimización del algoritmo de la base de datos. La idea central es realizar una lectura secuencial. La razón de esta lectura secuencial es que el método de almacenamiento del índice mysql es en forma de páginas de datos. El tamaño de cada página de datos es de 16 kb, que se puede calcular La cantidad de datos que se pueden almacenar, si lee secuencialmente, reducirá el cambio entre páginas de datos. Es decir, operaciones de E / S reducidas. No tener que acceder al disco varias veces puede mejorar mucho la eficiencia. Si eso permite que NLJ pueda leer secuencialmente y realizar coincidencias por lotes. ¿No va a despegar rápidamente?
  • En este momento, apareció el algoritmo BKA. Este algoritmo apareció en la versión de la base de datos después de la 5.7, que es la versión optimizada del algoritmo BNL. El proceso de consulta consiste en leer los datos de la tabla de unidades en lotes y almacenarlos en el búfer, y luego realizar la coincidencia por lotes (y esto Los identificadores asociados se ordenan) y luego realizan consultas de coincidencia por lotes.

4. Selección de la mesa de transmisión

  • Para utilizar de manera eficiente los tres algoritmos de unión mencionados anteriormente, esto implica la elección de tablas de conducción.
  • Si se trata del algoritmo Index Nested-Loop Join, debe elegir una tabla pequeña como tabla inicial; si es el algoritmo Block Nested-Loop Join: cuando el join_buffer_size es lo suficientemente grande, es lo mismo; cuando el join_buffer_size no es lo suficientemente grande (esta situación es más común) , La mesa pequeña debe seleccionarse como mesa de conducción.
  • Por lo tanto, la regla general a seguir es seleccionar tablas pequeñas como tablas de manejo. Las tablas pequeñas aquí no se refieren a tablas con volúmenes de datos pequeños, sino a tablas con volúmenes de datos pequeños en el búfer de unión después de la condición where se realiza.

5. Uso diario

  • De hecho, en nuestras consultas asociadas habituales, generalmente usamos el índice de clave principal para asociar el índice único de otra tabla, por lo que las consultas asociadas utilizadas están indexadas, por lo que la mayoría de ellas usa Index Nested-Loop Únase (antes de la versión 5.6) o BKA. Por lo tanto, en la optimización habitual, se basa principalmente en las condiciones dónde. No es que el rendimiento se desperdicie en asociaciones de mesa. Cuando consultamos la tabla inicial, filtramos directamente una gran parte y luego la verificamos directamente en función de la identificación de la clave principal. ¿Puede el rendimiento de la combinación ser deficiente? Por lo tanto, la optimización habitual es principalmente impulsar la selección de la tabla y controlar el rendimiento de la consulta de la tabla. Seleccione una mesa pequeña para la mesa de conducción y el índice de la mesa de conducción será lo mejor posible.

para resumir

  1. Habló sobre el proceso de consulta aproximado de los cuatro algoritmos.
  2. algoritmos de consulta mysql 3, con índice BKA (búfer de unión) NLJ sin índice BLN (búfer de unión)
  3. La elección de la mesa de conducción, elija una pequeña mesa de conducción (participando en joinbuffer con menos datos)
  4. La optimización diaria de join SQL es principalmente para impulsar la selección de la tabla y la optimización del índice de la tabla.

Supongo que te gusta

Origin blog.csdn.net/weixin_40413961/article/details/108719849
Recomendado
Clasificación