tables outer inner full mysql join

mysql - outer - ¿Por qué STRAIGHT_JOIN mejora tan drásticamente esta consulta, y qué significa cuando se escribe después de la palabra clave SELECT?



mysql join types (1)

Tengo la siguiente consulta MySql:

select t1.* from Table1 t1 inner join Table2 t2 on t1.CommonID = t2.CommonID where t1.FilterID = 1

Tarda unos 30 segundos en ejecutarse, lo cual era extraño, porque si comento la cláusula join o where toma menos de un segundo: es decir,

select t1.* from Table1 t1 where t1.FilterID = 1

o

select t1.* from Table1 t1 inner join Table2 t2 on t1.CommonID = t2.CommonID

cada toma menos de un segundo.

Luego está la palabra clave STRAIGHT_JOIN, de la que puedo encontrar una referencia, aquí: http://dev.mysql.com/doc/refman/5.0/en/join.html

STRAIGHT_JOIN es similar a JOIN, excepto que la tabla de la izquierda siempre se lee antes que la tabla de la derecha. Esto se puede usar para aquellos (pocos) casos en los que el optimizador de unión coloca las tablas en el orden incorrecto.

¿Qué? Puedo escribir:

select t1.* from Table1 t1 STRAIGHT_JOIN Table2 t2 on t1.CommonID = t2.CommonID where t1.FilterID = 1

y la consulta se ejecuta en menos de un segundo.

Aún más extraño, puedo escribir:

select STRAIGHT_JOIN t1.* from Table1 t1 inner join Table2 t2 on t1.CommonID = t2.CommonID where t1.FilterID = 1

y lleva menos de un segundo, y esta sintaxis no parece ser siquiera legal.

Supongo que el segundo ejemplo significa que se usará STRAIGHT_JOIN siempre que se escriba una UNIÓN INTERNA, pero no puedo encontrar ninguna documentación al respecto.

¿Qué está pasando aquí, y cómo puede el optimizador de "unirse" dar como resultado un rendimiento relativamente pobre? ¿Siempre debo usar STRAIGHT_JOIN? ¿Cómo puedo saber cuándo usarlo o no?

Table1 y Table2 tienen claves primarias enteras; FilterID es una clave externa a otra tabla; las columnas de CommonID ​​son ambas claves foráneas de una tercera tabla. Ambos tienen índices en ellos. El motor de la base de datos es InnoDB.

Gracias


¿Qué está pasando aquí, y cómo puede el optimizador de "unirse" dar como resultado un rendimiento relativamente pobre?

STRAIGHT_JOIN fuerza el orden de unión de las tablas, por lo que table1 se escanea en el bucle externo y table2 en el bucle interno.

El optimizador no es perfecto (aunque todavía es bastante decente), y la causa más probable es que las estadísticas estén desactualizadas.

¿Debería usar siempre STRAIGHT_JOIN

No, solo cuando el optimizador está mal. Esto puede ser si su distribución de datos está muy sesgada o no se puede calcular correctamente (por ejemplo, para índices espaciales o de texto completo).

¿Cómo puedo saber cuándo usarlo o no?

Debe recopilar las estadísticas, crear los planes de ambas maneras y comprender qué significan estos planes.

Si ves eso:

  1. El plan generado automáticamente no es óptimo y no se puede mejorar de la manera estándar,

  2. La versión STRAIGHT_JOIN es mejor, usted entiende que siempre lo hará y entenderá por qué siempre lo hará

, luego usa STRAIGHT_JOIN .