2011-01-14 17 views
11

Al unir dos tablas simples en columnas de clave primaria y colocar una condición de igualdad de adición, esto se puede hacer en la propia unión o en la cláusula where.¿Es mejor hacer un equi join en la cláusula from o en la cláusula

Por ejemplo, los siguientes son equiavalent. Mi pregunta es: ¿hay alguna razón para usar un estilo sobre el otro?

SELECT * 
FROM A 
INNER JOIN B ON A.A_ID = B.A_ID 
      AND A.DURATION = 3.00 

... vs:

SELECT * 
FROM A 
INNER JOIN B ON A.A_ID = B.A_ID 
WHERE A.DURATION = 3.00 
+2

supongo que para una consulta más compleja que mantiene la unión y las condiciones en el mismo lugar esta evitando el desplazamiento entre partes de la consulta – AJM

Respuesta

9

Es una cuestión de estilo. En general, querría poner las condiciones que definen la "forma" del conjunto de resultados en la cláusula FROM (es decir, aquellas que controlan qué filas de cada tabla se deben unir para producir un resultado), mientras que las condiciones que filtran el conjunto de resultados debe estar en la cláusula WHERE. Para INNER JOINs, los efectos son iguales, pero una vez que participan OUTER JOINs (LEFT, RIGHT), se siente mucho más claro.


En su primer ejemplo, me preguntan "¿qué tiene esto que ver con la Tabla B?" cuando encuentro esta extraña condición en JOIN. Mientras que en el segundo, puedo omitir la cláusula FROM (y todas las UNIONES) si no estoy interesado, y solo ver las condiciones que determinan si las filas se van a devolver en la cláusula WHERE.

1

es una cuestión de estilo. El optimizador hará lo mejor.

3

Para SQL Server 2000+, los planes de consulta para cada una de estas consultas serán idénticos, y por lo tanto también lo será el rendimiento.

Puede verificar esto utilizando SSMS para mostrar el plan de ejecución real para cada una de las consultas que presionen CTRL + M antes de ejecutar su consulta. El panel de resultados tendrá una pestaña adicional que le muestra el plan de ejecución. Verás que en este caso, los dos planes son iguales.

6

Es el tipo de JOIN que importa.
No hay diferencia, cualquiera de las versiones de la consulta proporcionada utilizará el mismo plan de ejecución porque se trata de una UNIÓN INTERNA.

Si se trata de una combinación externa (IE: izquierda, derecha), hay una enorme diferenciaentre las dos versiones porque los criterios WHERE se aplica después de la unión se hace. Si el criterio se especifica en la cláusula ON, se aplica el criterio antes de se realiza la UNIÓN, que puede hacer una diferencia considerable entre los conjuntos de resultados.

10

En general, no hay diferencia semántica.

Hay un caso de borde donde se puede hacer bien. Si el constructo (en desuso) GROUP BY ALL se agrega a la consulta como se ilustra a continuación.

DECLARE @A TABLE(A_ID INT, DURATION DECIMAL(3,2)) 
INSERT INTO @A VALUES(1,2.00) 

DECLARE @B TABLE(A_ID INT) 
INSERT INTO @B VALUES(1) 

/*Returns one row*/ 
SELECT * 
FROM @A A 
INNER JOIN @B B ON A.A_ID = B.A_ID 
WHERE A.DURATION = 3.00 
GROUP BY ALL A.A_ID, A.DURATION, B.A_ID 

/*Returns zero rows*/  
SELECT * 
FROM @A A 
INNER JOIN @B B ON A.A_ID = B.A_ID AND A.DURATION = 3.00 
GROUP BY ALL A.A_ID, A.DURATION, B.A_ID 
0
--Samples for time of join wheather can we write condition at where or ON 
create table #emp(id int ,teamid int) 
create table #team(tid int,name char(2)) 
insert into #emp values(1,1) 
insert into #emp values(2,1) 
insert into #emp values(3,2) 
insert into #emp values(4,0) 

insert into #team values(1,'A') 
insert into #team values(2,'B') 
insert into #team values(3,'C') 

--select * from #emp 
--select * from #team 

--on inner join => there is no difference in Query Exc. Plan 
--select * from #emp e join #team t on e.teamid=t.tid where e.teamid=2 
--select * from #emp e join #team t on e.teamid=t.tid and e.teamid=2 


/*on outetr join see the differnence If dealing with an OUTER JOIN (IE: LEFT, RIGHT), 
there is a huge difference between the two versions because the WHERE criteria is applied after the JOIN is made. 
If the criteria is specified in the ON clause, the criteria is applied before the JOIN is made which can made a considerable difference 
between the result sets.*/ 
select * from #emp e left join #team t on e.teamid=t.tid 
select * from #emp e left join #team t on e.teamid=t.tid where e.teamid=2 
select * from #emp e left join #team t on e.teamid=t.tid and (e.teamid=2 or t.tid=1) and t.name='A' 


drop table #emp 
drop table #team 
+0

favor ver explicación más abajo detallada que le ayuda a GRAP las cosas rápidamente – Siva

+0

No veo una explicación.Solo una repetición de lo que dijo OMG Ponies ... hace dos años. – Leigh

Cuestiones relacionadas