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:
El plan generado automáticamente no es óptimo y no se puede mejorar de la manera estándar,
La versión
STRAIGHT_JOIN
es mejor, usted entiende que siempre lo hará y entenderá por qué siempre lo hará
, luego usa STRAIGHT_JOIN
.