2010-10-09 21 views
10

He oído que las uniones deben preferirse a las consultas anidadas. ¿Es cierto en general? O puede haber escenarios donde uno sería más rápido que otro:Nested Query o Joins

por ej. que es la forma más eficiente para escribir una consulta ?:

Select emp.salary 
from employee emp  
where emp.id = (select s.id from sap s where s.id = 111) 

O

Select emp.salary  
from employee emp 
INNER JOIN sap s ON emp.id = s.id 
WHERE s.id = 111 
+0

¿Y si el estado en que se hace parte de la condición de unión? INNER JOIN sap s en emp.id = s.id y s.id = 111 – Tim

Respuesta

9

He oído que las uniones deben preferirse a las consultas anidadas. ¿Es cierto en general?

Depende de los requisitos y de los datos.

El uso de JOIN se corre el riesgo de duplicar la información en el conjunto de resultados para la tabla primaria si hay más de un registro secundario relacionado, porque JOIN devuelve las filas que coinciden. Lo que significa que si desea valores únicos de la tabla primaria mientras usa JOINs, debe ver usando DISTINCT o una cláusula GROUP BY. Pero nada de esto es una preocupación si se utiliza una subconsulta.

Además, las subconsultas no son todas iguales. Hay la evaluación recta, al igual que su ejemplo:

where emp.id = (select s.id from sap s where s.id = 111) 

... y la cláusula IN:

where emp.id IN (select s.id from sap s where s.id = 111) 

..., que coincidirá con cualquier valor de la (s) devueltos por la subconsulta cuando el la evaluación directa arrojará un error si s.id devuelve más de un valor. Pero también existe la cláusula EXISTS ...

WHERE EXISTS(SELECT NULL 
       FROM SAP s 
       WHERE emp.id = s.id 
       AND s.id = 111) 

El existe es diferente, ya que:

  • la cláusula SELECT no consigue evaluado - se puede cambiar a SELECT 1/0, que debe gatillo un error de división por cero pero no
  • devuelve verdadero/falso; verdadero basado en la primera instancia, se cumple el criterio, por lo que es más rápido cuando se trata de duplicados.
  • a diferencia de la cláusula IN, EXISTS permite comparar dos o más comparaciones de columnas al mismo tiempo, pero algunas bases de datos admiten la comparación tupla con el IN.
  • Es más legible
+0

+1, gracias por la respuesta completa. –

+0

¿Crees que hay situaciones en las que la cláusula 'IN' es mejor que' EXISTS'? –

+1

@Daniel Vassallo: No en este momento. Me pregunto si el enfoque EXISTS también evita el problema con una gran cantidad de valores para comparar con los que tiene IN en algunas bases de datos (en miles). –

0

Es mucho más rápido (y más fácil de escribir) para unir dos tablas en un índice que correr dos consultas separadas (incluso una subconsulta).

+0

¿Pero por qué? ¿Cuál es la diferencia en el plan de ejecución? –

+0

No hay diferencia porque MySQL lo optimizará para usar probablemente el JOIN y hacer lo mismo, pero lo verá ejecutando una consulta PRIMARY y una SUBQUERY. No estoy seguro de si esto afecta a una velocidad. Otra cosa es que estás uniendo semánticamente las dos tablas, ¿por qué no escribir esto? –

+0

@tandu, creo que para muchas consultas, las subconsultas ofrecen más claridad. Si solo quiere una pieza de datos de la otra tabla, está * mucho * más claro para que esté todo en un solo lugar (con una subconsulta) que para dividirla en la selección, desde/unirse, y potencialmente donde cláusula de la consulta principal. –

1

Si las consultas son lógicamente equivalentes, el optimizador de consultas debería poder hacer el mismo (mejor) plan de ejecución de cada una. En ese caso, el estilo de la consulta debe respaldar lo que se puede entender mejor (para mí, las subconsultas).