Usando la palabra clave JOIN o no

40

Las siguientes consultas SQL son las mismas:

SELECT column1, column2
FROM table1, table2
WHERE table1.id = table2.id;

SELECT column1, column2
FROM table1 JOIN table2 
ON table1.id = table2.id;

Y, sin duda, resulta en los mismos planes de consulta en todos los DBMS que he probado.

Pero de vez en cuando, leo o escucho una opinión de que uno es definitivamente mejor que el otro. Naturalmente, estas afirmaciones nunca se fundamentan con un explicación.

Donde trabajo, la segunda versión parece ser favorecida por la mayoría de los demás desarrolladores, y por eso también tiendo hacia ese estilo para minimizar la sorpresa. Pero en mi Corazón, realmente estoy pensando en el primero (ya que así es como aprendí originalmente it).

¿Es una de estas formas objetivamente mejor que la otra? Si no, ¿cuáles serían las razones para utilizar una sobre la otra?

    
pregunta SingleNegationElimination 22.05.2011 - 03:19

9 respuestas

57

Encuentro que la segunda forma es mejor. Puede que sea porque así lo aprendí, lo admito, pero tengo una razón concreta: la separación de preocupaciones. Poner los campos que está utilizando para unir las tablas en la cláusula where puede llevar a dificultades para comprender las consultas.

Por ejemplo, tome la siguiente consulta:

select *
from table1, table2, table3, table4
where table1.id = table2.id
and table2.id = table3.id
and table3.id = table4.id
and table1.column1 = 'Value 1'

La consulta anterior tiene condiciones de unión a la tabla y condiciones reales de lógica de negocios combinadas en un solo espacio. Con una consulta grande, esto puede ser muy difícil de entender.

Sin embargo, ahora toma este código:

select *
from table1 join table2 on table1.id = table2.id
join table3 on table2.id = table3.id
join table4 on table3.id = table4.id
where table1.column1 = 'Value 1'

En este caso, todo lo que tenga que ver con las tablas o cómo se relacionan está aislado de la cláusula from, mientras que la lógica de negocios real para la restricción de consulta está en la cláusula where. Creo que eso es mucho más comprensible, especialmente para consultas más grandes.

    
respondido por el Dustin Wilhelmi 22.05.2011 - 03:27
36

La sintaxis de unión reemplazó la antigua sintaxis de coma en 1992. Actualmente no hay razón para escribir código con la sintaxis de coma. No gana nada y está sujeto a algunos problemas que simplemente no tiene con la sintaxis explícita.

En primer lugar, a medida que obtiene consultas más complicadas, es muy fácil hacer una unión cruzada accidental al pasar por alto una condición donde. Esto es algo que la sintaxis de unión explícita puede evitar que ocurra, ya que obtendrá un error de sintaxis.

Si pretende una combinación cruzada, la sintaxis de la unión explícita lo dejará claro mientras que en la sintaxis implícita alguien que realiza el mantenimiento puede asumir que olvidó agregar la cláusula where.

Luego está el problema de las combinaciones izquierda y derecha que son problemáticas en al menos algunos dbs usando la sintaxis implícita. Están en desuso en SQL Server y, de hecho, no devuelven resultados correctos de manera realista, incluso en las versiones anteriores. Ninguna consulta que necesite una unión externa debe contener la sintaxis implícita en SQL Server.

Además, he visto preguntas aquí y en otros sitios donde se obtuvieron resultados incorrectos cuando las personas mezclan las uniones implícitas y explícitas (al agregar una unión izquierda, por ejemplo), por lo que es una mala idea combinarlas.

Finalmente, muchas personas que usan uniones implícitas no entienden realmente las uniones. Esta es una comprensión crítica que debe tener para consultar efectivamente una base de datos.

    
respondido por el HLGEM 22.05.2011 - 04:57
7

Ha. Simplemente encontré una posible respuesta a mi propia pregunta, mientras miraba la documentación de PostgreSQL . Para resumir lo que explica esta página, la consulta resultante sigue siendo la misma, pero el número de planes que debe considerar el optimizador crece exponencialmente con el número de uniones.

Después de aproximadamente seis de estas uniones, el número es tan grande que el tiempo para planificar la consulta puede ser notable, y después de alrededor de diez, el optimizador cambiará de una búsqueda exhaustiva de planes a una búsqueda probabilística, y es posible que no llegue. El plan óptimo.

Al establecer un parámetro de tiempo de ejecución, puede indicarle al planificador que trate las uniones internas y cruzadas explícitamente mencionadas de manera diferente a las uniones implícitas, forzándolas a la parte superior del plan y sin explorar otras opciones.

Cabe destacar que el comportamiento predeterminado es el mismo en ambos casos, y que obtener planes alternativos requiere el conocimiento de los aspectos internos de dbms y las peculiaridades de las tablas en cuestión para obtener un resultado diferente

    
respondido por el SingleNegationElimination 22.05.2011 - 04:04
7

Bueno, aquí está la vista de la teoría de conjuntos:

Cuando usa una coma para separar dos (o más) nombres de tablas, lo que pretende es el producto cartesiano. Cada fila de la tabla "izquierda" se "emparejará" (concatenada) con la de la tabla derecha.

Ahora, si escribe algo en la cláusula where, es como poner una condición en esta "concatenación" que indica qué filas deben "concatenar" con qué filas.

En realidad, esto es "unir" las filas :) y, por lo tanto, la palabra clave de unión que ayuda a proporcionar una sintaxis más legible y es más comprensible que "de hecho" quiera unirse en algunos valores comunes. Similar a lo que @Dustin ha aclarado anteriormente.

Ahora, cada DBMS es inteligente, es decir, no calcula el producto cartesiano primero y luego filtra los datos (es un gran desperdicio), sino que lo hace en función de la estructura de la consulta. Lo único en lo que puedo pensar es que cuando pides que se "una" es como hacer explícita la actividad de unión y probablemente te ayude a ejecutar el código más rápido (¿cuánto? Tendrás que crear un perfil y verlo) pero en la caso separado por comas, necesita algo de tiempo para "descubrir" la estrategia óptima. Puede que me equivoque, pero solo estoy haciendo una suposición educada sobre cómo se podría codificar ...

    
respondido por el PhD 22.05.2011 - 12:15
4

Creo que, en general, es mejor usar las instrucciones de JOIN para ese caso.

Si, en el futuro, surge una situación que requiere cambiar la declaración de un INNER JOIN a un OUTER JOIN, esto será mucho más fácil de hacer con la segunda declaración.

    
respondido por el Britt Wescott 22.05.2011 - 03:24
2

Cualquier RDBMS hará que sean lo mismo en términos de ejecución. Todo se reduce a si uno es más legible y expresivo.

Use el comando JOIN para que quede claro qué es una coincidencia de combinaciones y qué es la selección real, como en:

select name, deptname
from people p, departments d
where p.deptid = d.id and p.is_temp = 'Y'

vs.

select name, deptname
from people p
    inner join departments d on p.deptid = d.id
where p.is_temp = 'Y'

El último caso deja en claro de inmediato cuál es la condición de unión y cuál es el criterio de selección.

    
respondido por el Andy Lester 22.05.2011 - 03:57
1

Solo una vez he visto a los dos resultados en un conjunto diferente de optimizaciones y si la memoria me sirve, fue en ms-sql2k en una consulta realmente difícil. En ese ejemplo, el formulario antiguo usado con * = dio como resultado un rendimiento 4 veces más rápido. Nadie, incluyendo a nuestros técnicos de Microsoft, podría explicar por qué. Los chicos de MS lo etiquetaron como un error. Nunca lo he vuelto a ver.

Dado que la mayoría de los RDBMS son lo suficientemente inteligentes como para no hacer los cartesianos completos, la razón más importante que se me ocurre es no usarlos (además de que está depreciado) es que la mayoría de las personas menores de 30-35 con los que he trabajado tienen nunca he visto la forma anterior y se pierden terriblemente cuando la encuentran.

    
respondido por el Bill 23.05.2011 - 21:49
-1

El estilo antiguo ha quedado en desuso, no debe usarlo.

Ni siquiera debería haber un argumento sobre cuál es mejor o no. El nuevo código no debe usar la sintaxis antigua.

    
respondido por el Pieter B 23.04.2015 - 09:39
-4

Una de las razones de la sintaxis más concisa es que es más concisa, por lo que si te sientes cómodo es más fácil de leer. Pienso que el caso detallado es similar a escribir aritmética en COBOL, por ejemplo. MULTIPLICAR A POR B DAR C

    
respondido por el John Bickers 22.05.2011 - 12:42

Lea otras preguntas en las etiquetas