¿Qué cláusula se realiza primero en una instrucción SELECT
?
Tengo una duda en la consulta de select
sobre esta base.
considere el siguiente ejemplo
SELECT * FROM #temp A INNER JOIN #temp B ON A.id = B.id INNER JOIN #temp C ON B.id = C.id WHERE A.Name = 'Acb' AND B.Name = C.Name
Si, primero se comtesting la cláusula WHERE
y luego realiza INNER JOIN
Primero JOIN
y luego verifica la condición?
Si primero realiza la condición JOIN
y WHERE
; ¿Cómo puede funcionar más donde las condiciones para diferentes JOIN
s?
El order conceptual del procesamiento de consultas es:
1. FROM 2. WHERE 3. GROUP BY 4. HAVING 5. SELECT 6. ORDER BY
Pero esto es solo un order conceptual. De hecho, el motor puede decidir reorganizar las cláusulas. Aquí hay una testing. Vamos a hacer 2 tablas con 1000000 filas cada una:
CREATE TABLE test1 (id INT IDENTITY(1, 1), name VARCHAR(10)) CREATE TABLE test2 (id INT IDENTITY(1, 1), name VARCHAR(10)) ;WITH cte AS(SELECT -1 + ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) d FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t1(n) CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t2(n) CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t3(n) CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t4(n) CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t5(n) CROSS JOIN (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t6(n)) INSERT INTO test1(name) SELECT 'a' FROM cte
Ahora ejecute 2 consultas:
SELECT * FROM dbo.test1 t1 JOIN dbo.test2 t2 ON t2.id = t1.id AND t2.id = 100 WHERE t1.id > 1 SELECT * FROM dbo.test1 t1 JOIN dbo.test2 t2 ON t2.id = t1.id WHERE t1.id = 1
El aviso primero filtrará la mayoría de las filas en condición de join
, segundo en la condición de location. Mira los planes producidos:
1 TableScan – Pnetworkingicado: [Prueba]. [Dbo]. [Test2]. [Id] como [t2]. [Id] = (100)
2 TableScan – Pnetworkingicado: [Prueba]. [Dbo]. [Test2]. [Id] como [t2]. [Id] = (1)
Lo que significa que en la primera consulta optimizada se decidió primero evaluar la condición de join
para filtrar las filas, en la segunda se evaluó la cláusula where
primero.
El order lógico de las fases de procesamiento de consultas es:
FROM
– Incluyendo JOIN
s WHERE
GROUP BY
HAVING
SELECT
ORDER BY
Puede tener tantos como condiciones incluso en sus cláusulas WHERE
o WHERE
. Me gusta:
Select * from #temp A INNER JOIN #temp B ON A.id = B.id AND .... AND ... INNER JOIN #temp C ON B.id = C.id AND .... AND ... Where A.Name = 'Acb' AND B.Name = C.Name AND ....
Puede referirse a MSDN
Las filas seleccionadas por una consulta se filtran primero por las condiciones de unión de la cláusula FROM, luego por las condiciones de búsqueda de la cláusula WHERE, y luego por las condiciones de búsqueda de la cláusula HAVING. Las combinaciones internas se pueden especificar en la cláusula FROM o WHERE sin afectar el resultado final.
También puede usar SET SHOWPLAN_ALL ON
antes de ejecutar su consulta para mostrar el plan de ejecución de su consulta para que pueda medir la diferencia de performance en los dos.
puede referirse a esta optimization de combinación
SELECT * FROM T1 INNER JOIN T2 ON P1(T1,T2) INNER JOIN T3 ON P2(T2,T3) WHERE P(T1,T2,T3)
El algorithm de combinación de bucle nested ejecutaría esta consulta de la siguiente manera:
FOR each row t1 in T1 { FOR each row t2 in T2 such that P1(t1,t2) { FOR each row t3 in T3 such that P2(t2,t3) { IF P(t1,t2,t3) { t:=t1||t2||t3; OUTPUT t; } } } }