Unión interna vs donde

257

¿Hay alguna diferencia en el rendimiento (en Oracle) entre

Select * from Table1 T1 
Inner Join Table2 T2 On T1.ID = T2.ID

Y

Select * from Table1 T1, Table2 T2 
Where T1.ID = T2.ID

?

juan
fuente
1
solo para que conste, he visto que las consultas devuelven resultados diferentes solo al cambiar de una cláusula de combinación a una cláusula
where
12
@BlackTigerX: ¿Resultados diferentes? ¿Hubo alguna unión externa involucrada? Porque no veo cómo sucederían resultados diferentes entre un inner join ... oncriterio de combinación equivalente frente a un equivalente en la wherecláusula.
Shannon Severance
en la versión anterior de la base de datos join
Oracle
2
@MajidTaheri: ¿de cuántos años de una versión de Oracle estás hablando? Cualquier versión compatible con Oracle admite la notación JOIN.
Jonathan Leffler
Busque respuestas generales o mejores prácticas basadas en casos triviales. Me gustaría ver un "reencuentro" con cláusulas más complejas que involucren múltiples condiciones AND. Al menos con SQL Server hay un punto de cruce.
crokusek

Respuestas:

195

¡No! El mismo plan de ejecución, mira estas dos tablas:

CREATE TABLE table1 (
  id INT,
  name VARCHAR(20)
);

CREATE TABLE table2 (
  id INT,
  name VARCHAR(20)
);

El plan de ejecución para la consulta utilizando la unión interna:

-- with inner join

EXPLAIN PLAN FOR
SELECT * FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.id;

SELECT *
FROM TABLE (DBMS_XPLAN.DISPLAY);

-- 0 select statement
-- 1 hash join (access("T1"."ID"="T2"."ID"))
-- 2 table access full table1
-- 3 table access full table2

Y el plan de ejecución de la consulta utilizando una cláusula WHERE.

-- with where clause

EXPLAIN PLAN FOR
SELECT * FROM table1 t1, table2 t2
WHERE t1.id = t2.id;

SELECT *
FROM TABLE (DBMS_XPLAN.DISPLAY);

-- 0 select statement
-- 1 hash join (access("T1"."ID"="T2"."ID"))
-- 2 table access full table1
-- 3 table access full table2
kiewic
fuente
44
Realmente deseo ver si hay alguna documentación oficial de Oracle que diga sobre esto
4 Leave Cover el
68

Si el optimizador de consultas está haciendo su trabajo correctamente, no debería haber diferencia entre esas consultas. Son solo dos formas de especificar el mismo resultado deseado.

Craig Trader
fuente
22
Sí, el rendimiento debería ser el mismo. Pero la sintaxis SELECT * FROM Table1, Table2 WHERE ... is EVIL!
Joel Coehoorn el
2
Me resulta mucho más fácil comprender FOR INNER JOINS que la sintaxis SQL-92. Su experiencia puede ser diferente.
Craig Trader
25
Creo que la sintaxis WHERE es más fácil de leer que INNER JION. Supongo que es como Vegemite. La mayoría de las personas en el mundo probablemente lo encuentran asqueroso, pero a los niños criados comiéndolo les encanta.
ScottCher
3
Vegemite es realmente desagradable, pero, una vez más, me encanta el scrapple. Imagínate.
StingyJack
2
@Darryl Creo que los JOINs son más fáciles de leer porque la condición para unir las tablas se define inmediatamente allí en lugar de "en algún lugar" en la WHEREcláusula. Prefiero reservar la WHEREcláusula para limitar el conjunto de datos (por ejemplo WHERE DATE > (SYSDATE - 1)) en lugar de definir también cómo se relacionan las tablas entre sí (por ejemplo WHERE T1.ID = T2.ID). Para una tabla pequeña como el ejemplo en cuestión hace poca diferencia, pero para consultas grandes que involucran varias tablas y varias condiciones, creo que hace que la consulta sea mucho más fácil de entender.
ImaginaryHuman072889
61

Deberían ser exactamente lo mismo. Sin embargo, como práctica de codificación, preferiría ver Join. Articula claramente tu intención,

Nescio
fuente
8
Estoy de acuerdo. Especialmente si se está uniendo a varias tablas, es mucho más fácil analizar una instrucción select si está haciendo uniones explícitas.
Paul Morie
13
En efecto. Las uniones representan una relación semántica entre dos conjuntos de datos, pero donde sugiere un conjunto filtrado. +1
EightyOne Unite
26

El uso JOINhace que el código sea más fácil de leer, ya que se explica por sí mismo.

No hay diferencia en la velocidad ( lo acabo de probar ) y el plan de ejecución es el mismo.

usuario21241
fuente
Gracias. Estaba buscando compresión de velocidad entre estos dos métodos.
Farhad Navayazdan
14

No sé acerca de Oracle, pero sé que la antigua sintaxis está en desuso en SQL Server y eventualmente desaparecerá. Antes de usar esa sintaxis anterior en una nueva consulta, verificaría qué planea hacer Oracle con ella.

Prefiero la sintaxis más nueva en lugar de mezclar los criterios de combinación con otras condiciones necesarias. En la sintaxis más nueva, es mucho más claro qué crea la unión y qué otras condiciones se están aplicando. No es realmente un gran problema en una consulta corta como esta, pero se vuelve mucho más confuso cuando tienes una consulta más compleja. Dado que las personas aprenden sobre las consultas básicas, preferiría que las personas aprendan a usar la sintaxis de combinación antes de que la necesiten en una consulta compleja.

Y, una vez más, no conozco específicamente a Oracle, pero sé que la versión de SQL Server de la combinación izquierda de estilo antiguo es defectuosa incluso en SQL Server 2000 y da resultados inconsistentes (a veces una combinación izquierda a veces una combinación cruzada), por lo que nunca debería ser usado. Esperemos que Oracle no sufra el mismo problema, pero ciertamente las uniones izquierda y derecha pueden ser mucho más difíciles de expresar adecuadamente en la sintaxis anterior.

Además, según mi experiencia (y, por supuesto, esta es una opinión estrictamente personal, es posible que tenga una experiencia diferente), los desarrolladores que usan las uniones estándar ANSII tienden a comprender mejor qué es una unión y qué significa obtenerla. datos fuera de la base de datos. Creo que es porque la mayoría de las personas con una buena comprensión de la base de datos tienden a escribir consultas más complejas y me parece que es mucho más fácil de mantener utilizando el estándar ANSII que el estilo anterior.

HLGEM
fuente
1
Amén hermano. ¡Abajo los JOINERS!
ScottCher
14

[Por un punto extra ...]

El uso de la sintaxis JOIN le permite comentar más fácilmente la combinación, ya que todo está incluido en una línea. Esto puede ser útil si está depurando una consulta compleja

Como todos los demás dicen, son funcionalmente iguales, sin embargo, JOIN es más claro en cuanto a una declaración de intenciones. Por lo tanto, puede ayudar al optimizador de consultas en las versiones actuales de Oracle en ciertos casos (no tengo idea si lo hace), puede ayudar al optimizador de consultas en futuras versiones de Oracle (nadie tiene ninguna idea) o puede ayudar si cambia de proveedor de base de datos.

Chris Gill
fuente
2
O ... cambie fácilmente las UNIONES INTERIORES a UNIDADES IZQUIERDAS, para ver qué combinación está causando que pierda las filas esperadas. Hago esto porque hago toda la consulta a la vez. Si comentas INNER JOINS, tienes que hacer un proceso de eliminación. Toma más tiempo. ¡Pero +1 para ti porque esta es una de mis razones favoritas para INNER JOINS aparte de la legibilidad!
Matthew McPeak
13

Son lógicamente idénticos, pero en las versiones anteriores de Oracle que adoptaron la sintaxis ANSI, a menudo había errores con él en casos más complejos, por lo que a veces encontrarás resistencia de los desarrolladores de Oracle cuando lo usas.

David Aldridge
fuente
¿Las versiones anteriores de Oracle tenían errores con esto? Que tan temprano ¿Qué versión (s)?
ScottCher
Metalink tiene detalles ... aparecen por todas partes.
David Aldridge
7

El rendimiento debe ser idéntico, pero sugeriría usar la versión de unión debido a la claridad mejorada cuando se trata de uniones externas.

También se pueden evitar productos cartesianos no intencionales utilizando la versión de combinación.

Un tercer efecto es un SQL más fácil de leer con una condición WHERE más simple.

stili
fuente
Realmente creo que la clave son los efectos no intencionales donde el criterio es ambiguo. Si especifica el tipo de unión, sabe exactamente lo que está obteniendo. He encontrado que diferentes bases de datos e incluso diferentes versiones de la misma plataforma de base de datos manejarán valores nulos de manera diferente en una unión implícita. Cuando especifica izquierda / derecha interior / exterior, pasa el tiempo para pensar cuál es la correcta. Cuando utiliza el método ambiguo, asume que funciona de la manera que espera / pretende.
Steve Kallestad
6

No olvide que en Oracle, siempre que los atributos de la clave de combinación tengan el mismo nombre en ambas tablas, también puede escribir esto como:

select *
from Table1 inner join Table2 using (ID);

Esto también tiene el mismo plan de consulta, por supuesto.

cheduardo
fuente
Revertí la edición porque la revisión anterior cambió el significado de la respuesta
juan
5

En un escenario donde las tablas están en tercera forma normal, las uniones entre tablas no deberían cambiar. Es decir, unirse a CLIENTES y los PAGOS siempre deben ser los mismos.

Sin embargo, debemos distinguir las uniones de los filtros . Las uniones tratan sobre relaciones y los filtros tratan sobre particionar un todo.

Algunos autores, refiriéndose al estándar (es decir, Jim Melton; Alan R. Simon (1993). Comprender el nuevo SQL: una guía completa. Morgan Kaufmann. Pp. 11-12. ISBN 978-1-55860-245-8.) , escribió sobre los beneficios de adoptar la sintaxis JOIN sobre tablas separadas por comas en la cláusula FROM.

Estoy totalmente de acuerdo con este punto de vista.

Hay varias formas de escribir SQL y lograr los mismos resultados, pero para muchos de los que trabajan en equipo, la legibilidad del código fuente es un aspecto importante, y ciertamente separar cómo las tablas se relacionan entre sí de filtros específicos fue un gran salto en el sentido de aclarar la fuente código.

abrittaf
fuente
La unión interna en significa unión cruzada donde. La coma es una combinación cruzada con menor prioridad que las combinaciones de palabras clave. On vs "filter" es irrelevante para la unión interna. Los NF son irrelevantes para las consultas. Nada en el estándar promueve combinaciones de palabras clave sobre comas. Las optimizaciones triviales se tratan en y donde por igual. Esta respuesta es un montón de ideas falsas.
Filipinas
1) Supongo que @philipxy está tratando de decir "En la cláusula FROM, las tablas separadas por comas tienen el mismo significado que las tablas CROSS JOINed". Estoy de acuerdo con eso. Por supuesto, puede apegarse a la sintaxis antigua y eso puede coexistir con cláusulas JOIN. Los optimizadores RDBMS comprenderán perfectamente ambos casos como iguales (en caso de que sean equivalentes, por supuesto) y elaborarán el mismo plan.
Abrittaf
4

En PostgreSQL, definitivamente no hay diferencia: ambos equivalen al mismo plan de consulta. Estoy 99% seguro de que ese es también el caso de Oracle.

Nick Johnson
fuente
2

Ambos son uniones internas que hacen lo mismo, uno simplemente usa la sintaxis ANSI más nueva.

Bob Gettys
fuente
2

Funcionalmente son los mismos que se han dicho. Sin embargo, estoy de acuerdo en que hacer la unión es mejor para describir exactamente lo que quieres hacer. Muchas veces he pensado que sabía cómo quería consultar algo hasta que comencé a hacer las uniones y me di cuenta de que quería hacer una consulta diferente a la original en mi cabeza.

MattC
fuente
1

Es cierto que, funcionalmente, ambas consultas deben procesarse de la misma manera. Sin embargo, la experiencia ha demostrado que si selecciona de vistas que usan la nueva sintaxis de combinación, es importante estructurar sus consultas también. El optimizador de Oracle puede confundirse si una vista usa una declaración de "unión", pero una consulta que accede a la vista usa el método tradicional de unión en la cláusula "dónde".

JoshL
fuente
Eso es más un problema con las vistas que con las uniones.
inexistente
0

Aunque la identidad de dos consultas parece obvia, a veces suceden cosas extrañas. Llegué a la consulta que tiene diferentes planes de ejecución al mover el predicado de unión de JOIN a WHERE en Oracle 10g (para WHERE el plan es mejor), pero no puedo reproducir este problema en tablas y datos simplificados. Creo que depende de mis datos y estadísticas. Optimizer es un módulo bastante complejo y, a veces, se comporta mágicamente.

Es por eso que no podemos responder a esta pregunta en general porque depende de los elementos internos de la base de datos. Pero deberíamos saber que la respuesta tiene que ser ' no hay diferencias '.

greatvovan
fuente
0

Tuve este enigma hoy cuando inspeccioné uno de nuestros tiempos de espera de sp en producción, cambié una unión interna en una tabla construida a partir de un feed xml a una cláusula 'where' en su lugar ... el tiempo promedio de ejecución ahora es de 80 ms en 1000 ejecuciones, mientras que antes de que el promedio de ejecución fuera de 2.2 segundos ... la principal diferencia en el plan de ejecución es la desaparición de una búsqueda clave ... El mensaje no se sabrá hasta que haya probado usando ambos métodos.

salud.

trbullet81
fuente
0

Como dijo Kiewik, el plan de ejecución es el mismo.

La declaración JOIN es más fácil de leer, lo que hace que sea más fácil no olvidar la condición ON y obtener un producto cartesiano. Estos errores pueden ser bastante difíciles de detectar en consultas largas utilizando múltiples combinaciones de tipo: SELECT * FROM t1, t2 WHERE t1.id = t2.some_field.

Si olvida solo una condición de unión, obtendrá una consulta muy larga para ejecutar que devuelve demasiados registros ... realmente demasiados. Algunas personas usan un DISTINCT para parchear la consulta, pero aún es muy largo de ejecutar.

Esa es exactamente la razón por la cual, usar la declaración JOIN es seguramente la mejor práctica: una mejor capacidad de mantenimiento y una mejor legibilidad.

Más aún, si recuerdo bien, JOIN está optimizado con respecto al uso de memoria.

ROQUEFORT François
fuente
0

Tengo una adición a esa buena respuesta :

Eso es lo que se define como SQL92 y SQL89 respectivamente, no hay diferencia de rendimiento entre ellos, aunque puede omitir la palabra INNER (usar solo JOIN es lo suficientemente claro y en la consulta más simple, guarda 5 golpes de teclado, ahora imagine cuántos golpes hay en grandes unos)

Ivanzinho
fuente