MySQL tiene tres algoritmos para unirse: Unir bucle anidado + Unir hash + Ordenar unir unir y cómo verificar el block_nested_loop abierto (usando el buff de unión)

Todos sabemos cómo usar tablas de asociación de combinación SQL, pero esta vez estamos hablando del algoritmo para implementar la combinación. Hay tres algoritmos para la combinación, a saber, combinación de bucle anidado, combinación de hash y combinación de combinación de ordenación.

Se menciona en la documentación oficial de MySQL que MySQL solo es compatible con el algoritmo de unión Nested Loop Join

MySQL resuelve todas las combinaciones utilizando un método de combinación de bucle anidado. Esto significa que MySQL lee una fila de la primera tabla y luego encuentra una fila coincidente en la segunda tabla, la tercera tabla y así sucesivamente.
explicar salida

 

Por lo tanto, este artículo solo habla sobre Nested Loop Join.

NLJ usa un bucle de dos capas. La primera tabla se usa como bucle externo y la segunda tabla se usa como bucle interno. Cada registro del bucle externo se compara con el registro del bucle interno y la salida que cumple las condiciones se emite. Y NLJ tiene 3 tipos de algoritmos de subdivisión:

1 、 Unión de bucle anidado simple (SNLJ)

 

    // 伪代码
    for (r in R) {
        for (s in S) {
            if (r satisfy condition s) {
                output <r, s>;
            }
        }
    }

 

 

SNLJ es una exploración completa de bucle de dos niveles de las dos tablas conectadas, y se emiten los dos registros que cumplen las condiciones. Esto es para que las dos tablas hagan el producto cartesiano. El número de comparaciones es R * S, que es un algoritmo más violento y comparará.

2 、 Unión de bucle anidado de índice (INLJ)

 

    // 伪代码
    for (r in R) {
        for (si in SIndex) {
            if (r satisfy condition si) {
                output <r, s>;
            }
        }
    }

 

 

INLJ se optimiza sobre la base de SNLJ El índice disponible está determinado por la condición de conexión, y el índice se escanea en el Inner Loop sin escanear los datos en sí, mejorando así la eficiencia del Inner Loop.
El INLJ también tiene la desventaja de que si el índice escaneado es un índice no agrupado y necesita acceder a datos no indexados, se producirá una operación para volver a leer los datos en la tabla, lo que provocará una operación de E / S aleatoria más. .

3 、 Bloque de unión de bucle anidado (BNLJ)

En circunstancias normales, el optimizador de MySQL preferirá usar el algoritmo INLJ cuando el índice esté disponible, pero cuando no haya ningún índice disponible, o si se considera que el escaneo completo puede ser más rápido que usar el índice, no elegirá usar el algoritmo SNLJ demasiado tosco.
Aquí está el algoritmo BNLJ: BNLJ usa el búfer de unión sobre la base de SNLJ, y leerá los registros requeridos por el bucle interno en el búfer por adelantado para mejorar la eficiencia del bucle interno.

 

    // 伪代码
    for (r in R) {
        for (sbu in SBuffer) {
            if (r satisfy condition sbu) {
                output <r, s>;
            }
        }
    }

 

 

El nombre del parámetro que controla el tamaño del búfer de unión en MySQL es join_buffer_size.

Solo almacenamos las columnas usadas en el búfer de unión, no las filas completas.
tamaño de búfer de unión

De acuerdo con el manual de MySQL, join_buffer_size almacena en búfer las columnas que se utilizan.

Comparación de algoritmos (tamaño de tabla exterior R, tamaño de mesa interior S):

 

                   \
comparación de algoritmos \
Unión de bucle anidado simple Unión de bucle anidado de índice Bloquear unión de bucle anidado
Número de exploraciones externas 1 1 1
Tiempos de exploración de la tabla interna R 0
Número de registros leídos R + R * S R + RS_Matches
Numero de comparaciones R * S R * IndexHeight R * S
Número de espalda a la mesa 0 RS_Matches 0

En MySQL 5.6, la operación de retorno de la tabla de INLJ se ha optimizado, y Batched Key Access Join (el método de asociación de tablas para el acceso al índice por lotes, por lo que la traducción se puede omitir ...) y Multi Range Read (mrr, multi-range read)) , almacene en caché el rowid de los datos necesarios en la operación de unión y luego obtenga los datos en lotes, optimice la E / S de múltiples operaciones dispersas a menos operaciones por lotes y mejore la eficiencia.

 

¿Cómo MySQL verifica y habilita el algoritmo NLJ (Nested Loop Join)?

SELECT @@optimizer_switch;

index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,subquery_materialization_cost_based=on,use_index_extensions=on.

Cómo habilitar NLJ (combinación de bucle anidado)

Activar / desactivar block_nested_loop = activar / desactivar

set @@optimizer_switch = 'index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on';

Verificación abierta con éxito

EXPLAIN SELECT * FROM appt_appointment t1 JOIN phe_institution t2;

 

Supongo que te gusta

Origin blog.csdn.net/zw764987243/article/details/114384346
Recomendado
Clasificación