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

?


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

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.


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,


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.


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.


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.


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.


¿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.


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.


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.


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.


2

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


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.


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".


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 '.


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.



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.


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)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.