2009-07-07 15 views
6

Probablemente ya debería saber esto, pero ¿cuál es la diferencia entre las dos afirmaciones siguientes?SQL - ¿Diferencia entre estas uniones?

El anidado:

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 
     LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
    ON t2.table2_ID = t1.table1_ID 

El más tradicional de Ingreso:

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID 
    LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
+0

¿Dan el mismo resultado cuando las ejecuta? –

+0

+1 por hacerme ir "Hm ..." – Tomalak

+0

Es muchísimo más fácil entender el segundo que el primero, incluso si pones (parens) alrededor del LOJ en el primero. Esperando votar una buena respuesta en este caso. –

Respuesta

5

Bueno, es el orden de las operaciones ..

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 
     LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
    ON t2.table2_ID = t1.table1_ID 

podría ser reescrita como:

SELECT 
    t1.* 
FROM 
     table1 t1              -- inner join t1 
    INNER JOIN 
     (table2 t2 LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID) -- with this 
    ON t2.table2_ID = t1.table1_ID          -- on this condition 

Así que, básicamente, primero LEFT JOIN T2 con t3, en base a la condición de unión: table3_ID = table2_ID, entonces combinación interna t1 con t2 en table2_ID = table1_ID.

En su segundo ejemplo, primero INNER UNE t1 con t2, y luego IZQUIERDA UNIENDO la unión interna resultante con la tabla t3 en la condición table2_ID = table1_ID.

SELECT 
    t1.* 
FROM 
    table1 t1 
    INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID 
    LEFT JOIN table3 t3 ON t3.table3_ID = t2.table2_ID   

podría reescribirse como:

SELECT 
    t1.* 
FROM 
     (table1 t1 INNER JOIN table2 t2 ON t2.table2_ID = t1.table1_ID) -- first inner join 
    LEFT JOIN               -- then left join 
     table3 t3 ON t3.table3_ID = t2.table2_ID      -- the result with this 

EDITAR

me disculpo. Mi primer comentario fue incorrecto. Las dos consultas producirán los mismos resultados, pero puede haber una diferencia en el rendimiento, ya que la primera consulta puede realizar un proceso más lento que la segunda consulta en algunos casos (cuando la tabla 1 contiene solo un subconjunto de los elementos en la tabla 2) como LEFT JOIN ser ejecutado primero - y solo entonces cruzado con la tabla1. A diferencia de la segunda consulta que permite que el optimizador de consultas haga su trabajo.

+1

Claramente, el orden de las operaciones es diferente, pero ¿hay alguna diferencia real (rendimiento, resultados, cualquier cosa)? –

+1

Proporcione un ejemplo de datos donde las consultas arrojarán resultados diferentes. No pude generar ninguno. –

+0

Ok, gracias por los pensamientos sobre este tipo. Es más o menos como pensé entonces. Los resultados serán los mismos, pero las consultas pueden tener un rendimiento diferente. Creo que para facilitar el uso, cambiaré la consulta anterior (anidada) para usar la sintaxis más tradicional. – TehOne

4

Para su ejemplo específico, no creo que no debería haber ninguna diferencia en los planes de consulta generado, pero definitivamente hay una diferencia en la legibilidad. Tu segundo ejemplo es MUCHO más fácil de seguir.

Si invirtiera los tipos de combinaciones en el ejemplo, podría terminar con resultados muy diferentes.

SELECT t1.* 
FROM table1 t1 
    LEFT JOIN table2 t2 ON t2.table2_ID = t1.table1_ID 
    INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 

-- may not produce the same results as... 

SELECT t1.* 
FROM table1 t1 
    LEFT JOIN table2 t2 
     INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
    ON t2.table2_ID = t1.table1_ID 

Con base en el hecho de que el orden de las uniones SÍ importa en muchos casos - el pensamiento cuidadoso debe entrar en cómo usted está escribiendo su sintaxis de combinación. Si encuentra que el segundo ejemplo es lo que realmente está tratando de lograr, lo consideraría volver a escribir la consulta para que se puede poner más énfasis en el orden de su une ...

SELECT t1.* 
FROM table2 t2 
     INNER JOIN table3 t3 ON t3.table3_ID = t2.table2_ID 
     RIGHT JOIN table1 t1 ON t2.table2_ID = t1.table1_ID 
2

La mejor manera de ver qué es diferente en estas dos consultas es comparar el Plan de consulta para estas dos consultas.

No hay diferencia en los conjuntos de resultados para estos IF siempre hay filas en la tabla 3 para una fila determinada en la tabla2.

Lo probé en mi base de datos y la diferencia en los planes de búsqueda era 1. Para la primera consulta, el optimizador optó por hacer la combinación en la tabla 2 y la tabla 3 primero. 2.Para la segunda consulta, el optimizador optó por unirse primero a table1 y table2.

+0

Para mí, los planes de ejecución para mis consultas reales eran exactamente iguales. – TehOne

0

Debería ver ninguna diferencia en absoluto entre las dos consultas, siempre que el optimizador de su DBMS esté a la altura. Eso, sin embargo, incluso para las grandes plataformas de alto costo, no es una suposición con la que estoy seguro, por lo que no me sorprendería descubrir que los planes de consulta (y por consiguiente los tiempos de ejecución) variaban.

Cuestiones relacionadas