SQL explícito vs implícito se une


399

¿Hay alguna diferencia de eficiencia en una unión interna explícita frente a implícita? Por ejemplo:

SELECT * FROM
table a INNER JOIN table b
ON a.id = b.id;

vs.

SELECT a.*, b.*
FROM table a, table b
WHERE a.id = b.id;

11
Buena pregunta. Tengo curiosidad por qué se utiliza la unión explícita. ¿No es posible hacer todas las consultas sin él?
Andrew

66
use la palabra clave EXPLAIN para conocer la diferencia sobre ambas consultas ... use JOIN y vea la diferencia .. Si intenta en una tabla de más de 100k registros, puede ver la diferencia ...
Jeyanth Kumar

@andrew Mi pregunta era en realidad si la unión implícita era una forma de "pirateo" (como en "¿Una consulta que involucra más de una tabla, no usa una combinación? ¿Es un truco, no?")
bobobobo

3
Son diferentes, la unión implícita lo sorprenderá de vez en cuando al tratar con valores nulos; use la unión explícita y evite los errores que surgen cuando "¡nada cambió!"
BlackTigerX

1
No hay diferencia. ,es CROSS JOINcon la unión más flexible y INNER JOINes CROSS JOINcon ONigual WHEREpero unión más fuerte. Lo importante para la ejecución es cómo el DBMS optimiza las consultas.
philipxy

Respuestas:


132

En cuanto al rendimiento, son exactamente iguales (al menos en SQL Server).

PD: tenga en cuenta que la IMPLICIT OUTER JOINsintaxis está en desuso desde SQL Server 2005. (La IMPLICIT INNER JOINsintaxis como se usa en la pregunta todavía es compatible)

Desaprobación de la sintaxis JOIN "Old Style": solo una cosa parcial


44
@lomaxx, solo por razones de claridad, ¿podría especificar qué sintaxis de los 2 en la pregunta está en desuso?
J Wynia

8
¿Pueden proporcionar documentación de respaldo? Esto suena mal en múltiples niveles.
NotMe

21
¿Cómo desaprueba el estándar SQL?
David Crawshaw

77
@david Crenshaw, la unión implícita ya no está en el estándar y no lo ha sido durante 18 años.
HLGEM

11
Las llamadas "uniones implícitas" de la variedad 'interna' o 'cruzada' permanecen en el Estándar. SQL Server está desaprobando la sintaxis de combinación externa "antigua" (es decir, *=y =*) que nunca ha sido estándar.
cuando el

129

Personalmente, prefiero la sintaxis de unión, ya que aclara que las tablas se unen y cómo se unen. Intente comparar consultas SQL más grandes donde seleccione entre 8 tablas diferentes y tenga mucho filtrado en el dónde. Al usar la sintaxis de unión, separa las partes donde se unen las tablas, a la parte donde está filtrando las filas.


44
Estoy completamente de acuerdo, pero esto está fuera de tema. OP preguntó sobre la eficiencia.
villasv

56

En MySQL 5.1.51, ambas consultas tienen planes de ejecución idénticos:

mysql> explain select * from table1 a inner join table2 b on a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.02 sec)

mysql> explain select * from table1 a, table2 b where a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.00 sec)

table1tiene 166208 filas; table2Tiene alrededor de 1000 filas.

Este es un caso muy simple; de ninguna manera prueba que el optimizador de consultas no se confunda y genere diferentes planes en un caso más complicado.


Esta debería ser la respuesta aceptada. Esto es correcto, el plan es el mismo (o cercano a las declaraciones más grandes) pero la cantidad de registros será drástica, lo que provocará una diferencia en el rendimiento.
SovietFrontier

37

La segunda sintaxis tiene la posibilidad no deseada de una unión cruzada: puede agregar tablas a la parte FROM sin la correspondiente cláusula WHERE. Esto se considera dañino.


¿Qué sucede si los nombres de tabla en la cláusula from se generan a partir de las tablas utilizadas en la cláusula where?
Jus12

también puede hacer una unión cruzada con la sintaxis explícita JOIN. ( stackoverflow.com/a/44438026/929164 ) probablemente haya querido decir que es menos estricto y, por lo tanto, más propenso a errores de usuario.
Daniel Dubovski

15

La primera respuesta que dio utiliza lo que se conoce como sintaxis de unión ANSI, la otra es válida y funcionará en cualquier base de datos relacional.

Estoy de acuerdo con grom en que debe usar la sintaxis de unión ANSI. Como decían, la razón principal es la claridad. En lugar de tener una cláusula where con muchos predicados, algunos de los cuales unen tablas y otros restringen las filas devueltas con la sintaxis de unión ANSI, deja en claro qué condiciones se utilizan para unir sus tablas y cuáles se usan para restringir resultados.


5

En cuanto al rendimiento, son exactamente iguales (al menos en SQL Server), pero tenga en cuenta que están despreciando esta sintaxis de combinación y no es compatible con sql server2005 de fábrica.

Creo que está pensando en los operadores obsoletos * = y = * vs. "combinación externa".

Acabo de probar los dos formatos dados y funcionan correctamente en una base de datos SQL Server 2008. En mi caso, arrojaron planes de ejecución idénticos, pero no podía decir con seguridad que esto siempre sería cierto.


5

@lomaxx: Solo para aclarar, estoy bastante seguro de que ambas sintaxis anteriores son compatibles con SQL Serv 2005. Sin embargo, la sintaxis a continuación NO es compatible

select a.*, b.*  
from table a, table b  
where a.id *= b.id;

Específicamente, la unión externa (* =) no es compatible.


2
Francamente, no lo usaría incluso en SQL Server 2000, la sintaxis * = a menudo da respuestas incorrectas. A veces los interpreta como uniones cruzadas.
HLGEM

2

En algunas bases de datos (especialmente Oracle), el orden de las combinaciones puede marcar una gran diferencia en el rendimiento de las consultas (si hay más de dos tablas). En una aplicación, tuvimos literalmente dos órdenes de magnitud de diferencia en algunos casos. El uso de la sintaxis de unión interna le da control sobre esto, si usa la sintaxis de sugerencias correcta.

No especificó qué base de datos está utilizando, pero la probabilidad sugiere SQL Server o MySQL donde no hay una diferencia real.


1
Leigh, también puedes usar las sugerencias en uniones implícitas.
SquareCog

1
En Oracle, es extremadamente raro que el orden de unión afecte el plan de ejecución de manera significativa. Vea este artículo de Jonathan Lewis para una explicación.
Jon Heller

1

Como ha dicho Leigh Caldwell, el optimizador de consultas puede producir diferentes planes de consulta en función de lo que funcionalmente se parece a la misma instrucción SQL. Para leer más sobre esto, eche un vistazo a las siguientes dos publicaciones de blog:

Una publicación del equipo de Oracle Optimizer

Otra publicación del blog "Datos Estructurados"

Espero que encuentres esto interesante.


Mike, la diferencia de la que están hablando es que debes asegurarte de que si especificas una unión explícita, especificas la condición de unión para unirse, no el filtro. Notará que para consultas semánticamente correctas, el plan ejecutivo es el mismo.
SquareCog

1

En cuanto al rendimiento, no debería hacer ninguna diferencia. La sintaxis de unión explícita me parece más clara, ya que define claramente las relaciones entre las tablas en la cláusula from y no satura la cláusula where.


0

Básicamente, la diferencia entre los dos es que uno está escrito en la forma antigua, mientras que el otro está escrito en la forma moderna. Personalmente, prefiero el script moderno que usa las definiciones interna, izquierda, externa y derecha porque son más explicativas y hacen que el código sea más legible.

Cuando se trata de uniones internas, tampoco hay una diferencia real en la legibilidad, sin embargo, puede complicarse cuando se trata de uniones izquierdas y derechas, ya que en el método anterior obtendría algo como esto:

SELECT * 
FROM table a, table b
WHERE a.id = b.id (+);

Lo anterior es la manera antigua de cómo se escribe una combinación izquierda en lugar de lo siguiente:

SELECT * 
FROM table a 
LEFT JOIN table b ON a.id = b.id;

Como puede ver visualmente, la forma moderna de cómo se escribe el script hace que la consulta sea más legible. (Por cierto, lo mismo ocurre con las uniones correctas y un poco más complicado para las uniones externas).

Volviendo a la placa de la caldera, al compilador de SQL no le importa cómo se escribe la consulta, ya que las maneja de la misma manera. He visto una combinación de ambos en las bases de datos Oracle que han tenido a muchas personas escribiendo en ella, tanto mayores como jóvenes. Nuevamente, se reduce a lo legible que es el script y al equipo con el que se está desarrollando.


-1

En mi experiencia, el uso de la sintaxis cross-join-with-a-where-clause a menudo produce un plan de ejecución con daño cerebral, especialmente si está utilizando un producto Microsoft SQL. La forma en que SQL Server intenta estimar los recuentos de filas de la tabla, por ejemplo, es salvajemente horrible. El uso de la sintaxis de unión interna le brinda cierto control sobre cómo se ejecuta la consulta. Entonces, desde un punto de vista práctico, dada la naturaleza atávica de la tecnología de base de datos actual, debe ir con la unión interna.


55
¿Tiene alguna prueba de ésto? Porque la respuesta aceptada dice lo contrario.
cimmanon
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.