2008-09-04 26 views
311

¿Hay alguna diferencia de eficiencia en una combinación interna explícita vs implícita? Por ejemplo:Vinculación explícita vs implícita de SQL

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; 
+7

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

+4

use la palabra clave EXPLAIN para saber la diferencia sobre ambas consultas ... use JOIN y vea la diferencia ... Si prueba en una tabla más de 100k registros, puede ver la diferencia ... –

+0

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

Respuesta

101

En cuanto al rendimiento, que son exactamente los mismos (al menos en SQL Server).

PS: Tenga en cuenta que la sintaxis IMPLICIT OUTER JOIN está obsoleta desde SQL Server 2005. (La sintaxis IMPLICIT INNER JOIN tal como se utiliza en la pregunta sigue siendo apoyado)

Deprecation of "Old Style" JOIN Syntax: Only A Partial Thing

+0

sintaxis de unión implícita es compatible con SQL Server 2005 de fábrica, pero sí, es una mala idea. –

+1

Aunque prefiero la sintaxis explícita, ¿puedes explicar cómo pueden estar desaprobando las uniones implícitas? La idea de que podría ser obsoleta parece extraña y la sugerencia de que no son compatibles con SQL 2K5 no es correcta. – BlackWasp

+7

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

110

Personalmente prefiero la sintaxis unirse como sus marcas es más claro que las tablas están unidas y cómo se unen. Intente comparar consultas SQL más grandes en las que seleccione entre 8 tablas diferentes y tenga mucho filtrado en where. Al usar la sintaxis de unión, separa las partes donde se unen las tablas, a la parte donde está filtrando las filas.

+0

Estoy completamente de acuerdo, pero esto está fuera de tema. OP preguntó acerca de la eficiencia. – VillasV

4

En cuanto a rendimiento, son exactamente iguales (al menos en SQL Server), pero tenga en cuenta que están desaprobando esta sintaxis de unión y no es compatible con sql server2005 fuera de la caja.

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

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

2

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

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

+1

Leigh, también puede usar los consejos en combinaciones implícitas. – SquareCog

+1

En Oracle es extremadamente raro que la orden de unión afecte el plan de ejecución de una manera significativa. Ver [este artículo] (http://jonathanlewis.wordpress.com/2006/11/03/table-order/) por Jonathan Lewis para una explicación. –

6

@lomaxx: Solo para aclarar, estoy bastante seguro de que tanto por encima de sintaxis están soportados por SQL Serv 2005. La siguiente sintaxis no se admite sin embargo

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

En concreto, la combinación externa (* =) no es apoyado.

+1

Francamente, no lo usaría ni siquiera en SQL Server 2000, la sintaxis * = a menudo da respuestas incorrectas. A veces los interpreta como combinaciones cruzadas. – HLGEM

14

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 dijeron, 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 que restringen las filas devueltas con la sintaxis de unión ANSI, usted está aclarando certeramente las condiciones que se utilizan para unir sus tablas y que se usan para restringir el resultados.

1

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

One posting from the Oracle Optimizer Team

Another posting from the "Structured Data" blog

Espero que encuentre este interesante.

+0

Mike, la diferencia de la que están hablando es que debe asegurarse de que si especifica una unión explícita, especifica la * condición de unión * para unirse, no el filtro. Notará que para las consultas semánticamente correctas, el plan del ejecutivo es el mismo. – SquareCog

31

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.

+0

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

1

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

38

En MySQL 5.1.51, ambos tienen planes de ejecución de consultas 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) 

table1 ha 166208 filas; table2 tiene alrededor de 1000 filas.

Este es un caso muy simple; de ninguna manera demuestra que el optimizador de consultas no se confundiría y generaría diferentes planes en un caso más complicado.

0

En mi experiencia, el uso de la sintaxis cross-join-with-a-where-clause a menudo produce un plan de ejecución dañado, especialmente si está utilizando un producto Microsoft SQL. La forma en que SQL Server intenta estimar los recuentos de filas de las tablas, por ejemplo, es salvajemente horrible. El uso de la sintaxis de combinación interna le da 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.

+2

¿Tiene alguna prueba de esto? Porque la [respuesta aceptada] (http://stackoverflow.com/a/44932/1652962) dice lo contrario. – cimmanon

Cuestiones relacionadas