Análisis profundo de mysql join

Hoy, al consultar la conexión de la tabla mysql, encontré un artículo sobre el análisis de profundidad de unión que se siente muy bien, y la explicación está en su lugar. Lo compartiré con ustedes aquí.

Introducción a unirse

Consulta conjunta de varias tablas, hay uniones internas, uniones externas, uniones derechas, uniones izquierdas y uniones naturales.
mysql-join-01.png

Producto Descartes CROSS JOIN

El producto cartesiano es forzar cada registro de la tabla A y cada registro de la tabla B juntos. Por lo tanto, si la tabla A tiene n registros y la tabla B tiene m registros, el resultado del producto cartesiano producirá n * m registros.

Conexión internaINNER JOIN

Hay cuatro formas de escribir INNER JOIN, WHERE (combinación equivalente), STRAIGHT_JOIN, JOIN (INNER omitido).
La combinación interna es la operación de combinación más utilizada. Desde el punto de vista matemático, es encontrar la intersección de las dos tablas, desde el punto de vista del producto cartesiano, es seleccionar el registro de la palabra ON del producto cartesiano.

Conexión izquierdaLEFT JOIN

La intersección de las dos tablas más los datos restantes en la tabla de la izquierda. Desde la perspectiva del producto cartesiano, primero selecciona los registros donde se cumple la condición de la cláusula ON del producto cartesiano y luego agrega los registros restantes en la tabla de la izquierda.

Conexión correctaRIGHT JOIN

La intersección de las dos tablas más el resto de los datos de la tabla de la derecha. Desde la perspectiva del producto cartesiano, primero selecciona los registros donde se cumple la condición de la cláusula ON del producto cartesiano y luego agrega los registros restantes en la tabla de la derecha.

Unión externaOUTER JOIN

La unión externa consiste en encontrar la unión de dos conjuntos. Desde la perspectiva del producto cartesiano, es seleccionar los registros donde se cumple la condición de la cláusula ON del producto cartesiano, luego agregar los registros restantes en la tabla de la izquierda y finalmente agregar los registros restantes en la tabla de la derecha.
MYSQL no admite OUTER JOIN, pero se puede implementar mediante la operación UNION en los resultados de las combinaciones izquierda y derecha.

Cláusula USING

Cuando el diseño del esquema usa el mismo estilo de nomenclatura para las columnas de la tabla unida, puede usar la sintaxis USING para simplificar la sintaxis ON, el formato es: USING (column_name).

LA NATURALEZA ÚNETE

La conexión natural es una versión simplificada de la cláusula USING, que encuentra las mismas columnas en las dos tablas como condición de conexión para conectarse. Hay conexiones naturales izquierdas, conexiones naturales correctas y conexiones naturales ordinarias.

Principio de unión

NLJ (unión de bucle anidado, algoritmo de bucle anidado)

Table1 maneja la mesa y table2 maneja la mesa. La mesa de conducción impulsará la mesa impulsada para las operaciones de conexión.

  1. Cargue la tabla de controladores y busque el primer registro de la tabla de controladores.
  2. Cargue la tabla impulsada, escanee la tabla impulsada desde el principio, busque los registros que coincidan con el primer registro de la tabla impulsada uno por uno y luego conéctelos para formar un registro en la tabla de resultados.
  3. Después de ser buscado por la tabla conducida, tome el segundo registro de la tabla conducida. Luego, cargue la tabla impulsada nuevamente, escanee la tabla impulsada desde el principio, busque los registros que coincidan con el segundo registro de la tabla impulsada uno por uno y conéctelos para formar un registro en la tabla de resultados.
  4. Repita las operaciones anteriores hasta que se procesen todos los registros de la tabla de unidades. Ésta es la idea básica del algoritmo de conexión de bucle anidado. Solo se pasa una fila al ciclo interno a la vez, por lo que el ciclo de memoria debe ejecutarse tantas veces como filas haya en el ciclo externo (el conjunto de resultados).

Tipos de conexión de la tabla t1, t2, t3:

Table Join Type
t1 range
t2 ref
t3 ALL

Procesamiento real:

for each row in t1 matching range {
    for each row in t2 matching reference key {
        for each row in t3 {
            if row satisfies join conditions, send to client
        }
    }
}

Algoritmo BNLJ (Bloque de unión de bucle anidado, algoritmo de bloque de bucle anidado)

Optimización de NLJ. La idea general es crear un área de búfer para recuperar varios registros de la tabla de unidades a la vez.
Almacene las filas / conjunto de resultados del bucle externo en el búfer de unión y compare cada fila del bucle interno con los registros de todo el búfer, reduciendo así el número de bucles internos.

Procesamiento real:

for each row in t1 matching range {
    for each row in t2 matching reference key {
        store used columns from t1, t2 in join buffer
        if buffer is full {
            for each row in t3 {
                for each t1, t2 combination in join buffer {
                    if row satisfies join conditions, send to client
                }
            }
            empty join buffer
        }
    }
}
if buffer is not empty {
    for each row in t3 {
        for each t1, t2 combination in join buffer {
            if row satisfies join conditions, send to client
        }
     }
}

Ejemplo de fila exterior table100:

El conjunto de resultados del bucle externo es de 100 filas y la tabla interna debe escanearse 100 veces para usar el algoritmo NLJ.
Si usa el algoritmo BNL, primero coloque las 10 filas de registros leídos de la tabla Outer Loop (tabla externa) cada vez en el búfer de unión (de acuerdo con el tamaño de join_buffer_size), y luego haga coincidir directamente estas 10 filas de datos en el Tabla InnerLoop (tabla interna). El bucle de memoria se puede comparar con estas 10 filas a la vez, por lo que solo se necesitan 10 comparaciones y el escaneo de la tabla interna se reduce en 9/10.
Por lo tanto, el algoritmo BNL puede reducir significativamente el número de exploraciones de la tabla de bucle interno.

MySQL usa Join Buffer tiene los siguientes puntos:

  • La variable join_buffer_size determina el tamaño del búfer.
  • El búfer de combinación solo se puede usar cuando el tipo de combinación es todo, índice y rango.
  • Cada unión que se puede almacenar en búfer asignará un búfer, lo que significa que una consulta puede eventualmente usar varios búferes de unión.
  • La primera tabla que no sea constante no asignará el búfer de unión, incluso si su tipo de escaneo es todo o índice.
  • El búfer de combinación se asignará antes de la combinación y se liberará después de que se ejecute la consulta.
  • Solo las columnas que participan en la combinación se almacenarán en el búfer de combinación, no la fila de datos completa.

usar

En la versión 5.6 y posteriores, el parámetro block_nested_loop en el parámetro de gestión del optimizador optimizer_switch controla si se utiliza BNL en el optimizador. Está activado de forma predeterminada. Si está desactivado, el optimizador seleccionará el algoritmo NLJ al elegir el método de unión.
Activar o desactivar:SET SESSION optimizer_switch ='block_nested_loop=off';

Factores que afectan el desempeño

Número de ciclos internos

Suponga que tabla1 tiene 100 registros y tabla2 tiene 10,000 registros.
El número de ejecuciones de instrucciones es 100 * 10000 veces.
Table1 controla table2: table1 se carga una vez, table2 se carga 100 veces.
Table2 controla table1: table1 se carga 10,000 veces y table2 se carga una vez.
Por lo tanto, table1 controla table2 de manera más eficiente.
Conducir una mesa grande junto a una mesa pequeña puede reducir el número de bucles internos, mejorando así la eficiencia de la conexión.

Partido rápido

La exploración de la tabla conducida en busca de registros adecuados puede considerarse una operación de consulta. La creación de índices en la tabla conducida puede mejorar la eficiencia de las consultas.

Clasificar

La clasificación de la mesa principal primero clasificará la mesa principal y luego ejecutará el algoritmo de unión de la tabla. Ordenar la tabla conducida es ordenar el conjunto de resultados después de realizar la unión de la tabla.
Por lo tanto, se prefiere seleccionar los atributos de la tabla de conducción para clasificar.

JOIN optimiza el número de bucles internos

El número de bucles internos se ve afectado por el número de registros en la tabla de unidades. Cuantos más registros haya en la tabla de unidades, más bucles internos y menor será la eficiencia de la conexión, así que intente utilizar una tabla pequeña para impulsar una tabla grande.
En la conexión de la izquierda, la mesa de la izquierda es la mesa conducida y la mesa de la derecha es la mesa conducida.
En la conexión derecha, la mesa derecha es la mesa conducida y la mesa izquierda es la mesa conducida.
Pero la unión interna es diferente Según la idea del algoritmo de bucle anidado, el conjunto de resultados de la conexión interna table1 table2 y la conexión interna table2 table1 son iguales.
STRAIGHT_JOIN fuerza a la mesa de la izquierda a unirse a la mesa de la derecha.
El propio Optimizador de MYSQL optimizará las combinaciones internas, y la estrategia de optimización es que la tabla pequeña impulsa la tabla grande como se mencionó anteriormente.

ÚNETE a la optimización y la coincidencia rápida

La operación UNIR de las dos tablas es buscar continuamente registros de la tabla inicial y luego buscar y conectar los registros coincidentes en la tabla conducida. La esencia de este proceso son las operaciones de consulta. Para optimizar las operaciones de consulta, la indexación es la forma más común.

ÚNETE A LA IZQUIERDA

En la conexión de la izquierda, la mesa de la izquierda es la mesa conducida y la mesa de la derecha es la mesa conducida. Desea encontrar rápidamente los registros coincidentes en la tabla conducida, por lo que creamos un índice en la tabla correcta para mejorar el rendimiento de la conexión.

UNIRSE CORRECTAMENTE

En la conexión derecha, la mesa derecha es la mesa conducida y la mesa izquierda es la mesa conducida. Desea encontrar rápidamente registros coincidentes en la tabla conducida, por lo que creamos un índice en la tabla de la izquierda para mejorar el rendimiento de la conexión.

UNIR INTERNAMENTE

MySQL Optimizer optimizará las combinaciones internas. No importa quién se conecte o quién, las tablas pequeñas se utilizan para manejar tablas grandes. Por lo tanto, si desea optimizar las combinaciones internas, puede crear índices en tablas grandes para mejorar el rendimiento de la conexión.
También tenga en cuenta que al crear índices en tablas pequeñas, MySQL Optimizer pensará que es más rápido usar tablas grandes para manejar tablas pequeñas y, en su lugar, usar tablas grandes para manejar tablas pequeñas.

Unión de varias mesas

Lo anterior es una conexión de dos mesas y la conexión de varias mesas es la misma. Descubra la mesa conductora y la mesa conducida, y cree un índice en la mesa conducida para mejorar el rendimiento de la conexión.

En resumen, para optimizar JOIN desde la perspectiva de un emparejamiento rápido, primero averigüe quién es la mesa conductora y quién es la mesa conducida, y luego cree un índice en la mesa conducida.

ORGANIZACIÓN DE OPTIMIZACIÓN UNIRSE

La clasificación se divide en: clasificación de atributos conectados y clasificación de atributos no conectados

Ordenar atributos de conexión

Al ordenar los atributos de conexión, los atributos de la tabla inicial deben seleccionarse como condiciones en la tabla de clasificación.
Ejemplo: table1 es una tabla grande, table2 es una tabla pequeña, table1 y table2 están conectados, la condición de conexión table1.id = table2.id, el id del atributo de conexión está ordenado.
Table1 es una tabla grande y table2 es una tabla pequeña. Por lo tanto, table2 es la tabla conducida y table1 es la tabla conducida.

Método 1: Después de que ORDER BY table1.id
ejecuta el algoritmo de combinación de tablas, el conjunto de resultados se ordena, lo cual es ineficaz.
Método 2: ORDER BY table2.id
ordena primero table2 y luego ejecuta el algoritmo de unión de tablas. eficiente.

Ordenar atributos no conectados

Porque MySQL Optimizer se optimizará de acuerdo con la "estrategia de mesa pequeña que conduce a una mesa grande". Al ordenar atributos no unidos de una tabla grande, considere usar STRAIGHT_JOIN para hacer que la tabla grande controle la tabla pequeña.
Ejemplo: table1 es una tabla grande, table2 es una tabla pequeña, table1 y table2 están conectados, la condición de conexión table1.id = table2.id, el tipo de campo del atributo no conectado table1 está ordenado.
Resultado de la operación real: MySQL Optimizer utilizará table2 para impulsar table1. Ahora tenemos que ordenar el atributo de tipo de table1. Table1 es una tabla conducida, lo que inevitablemente conducirá a un uso de ordenación temporal del conjunto de resultados después de la conexión (más serio que el uso de ordenamiento de archivos). Entonces usamos STRAIGHT_JOIN para hacer que la tabla grande table1 controle la tabla pequeña table2.

El autor de este artículo escribe muy bien otros artículos y vale la pena aprender. Si estás interesado, puedes visitar su blog . Al final del artículo hay un tutorial sobre otros aspectos de mysql.

Este blog se reimprime en http://www.apeit.cn/mysql-join-x167q , gracias nuevamente por compartir

Supongo que te gusta

Origin blog.csdn.net/weixin_42575020/article/details/113586832
Recomendado
Clasificación