哪个执行第一个 WHERE 子句或 JOIN 子句
Which performs first WHERE clause or JOIN clause
哪个子句在 SELECT
语句中首先执行?
在此基础上select
查询有疑问
考虑下面的例子
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
是否,首先检查WHERE
子句,然后执行INNER JOIN
先JOIN
然后检查条件?
如果先执行JOIN
再执行WHERE
条件;它如何针对不同的 JOIN
s 执行更多的 where 条件?
可以参考MSDN
The rows selected by a query are filtered first by the FROM clause
join conditions, then the WHERE clause search conditions, and then the
HAVING clause search conditions. Inner joins can be specified in
either the FROM or WHERE clause without affecting the final result.
您还可以在执行查询之前使用SET SHOWPLAN_ALL ON
来显示查询的执行计划,以便衡量两者的性能差异。
查询处理阶段的逻辑顺序是:
FROM
- 包括 JOIN
s
WHERE
GROUP BY
HAVING
SELECT
ORDER BY
即使在 JOIN
或 WHERE
子句中也可以有任意多个条件。喜欢:
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 ....
查询处理的概念顺序是:
1. FROM
2. WHERE
3. GROUP BY
4. HAVING
5. SELECT
6. ORDER BY
但这只是概念上的顺序。事实上,引擎可能会决定重新排列条款。这是证据。让我们制作 2 个表,每个表有 1000000 行:
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
现在 运行 2 个查询:
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
请注意,第一个查询会在 join
条件中过滤掉大部分行,但第二个查询会在 where
条件中过滤掉。查看生成的计划:
1 TableScan - Predicate:[Test].[dbo].[test2].[id] as [t2].[id]=(100)
2 TableScan - Predicate:[Test].[dbo].[test2].[id] as [t2].[id]=(1)
这意味着在优化的第一个查询中,引擎决定首先评估 join
条件以过滤掉行。在第二个查询中,它首先计算 where
子句。
你可以参考这个join optimization
SELECT * FROM T1 INNER JOIN T2 ON P1(T1,T2)
INNER JOIN T3 ON P2(T2,T3)
WHERE P(T1,T2,T3)
嵌套循环连接算法将按以下方式执行此查询:
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;
}
}
}
}
如果您是为了 logical query processing
的问题来到本站,您确实需要阅读 this article on ITProToday by Itzik Ben-Gan。
Figure 3: Logical query processing order of query clauses
1 FROM
2 WHERE
3 GROUP BY
4 HAVING
5 SELECT
5.1 SELECT list
5.2 DISTINCT
6 ORDER BY
7 TOP / OFFSET-FETCH
哪个子句在 SELECT
语句中首先执行?
在此基础上select
查询有疑问
考虑下面的例子
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
是否,首先检查
WHERE
子句,然后执行INNER JOIN
先
JOIN
然后检查条件?
如果先执行JOIN
再执行WHERE
条件;它如何针对不同的 JOIN
s 执行更多的 where 条件?
可以参考MSDN
The rows selected by a query are filtered first by the FROM clause join conditions, then the WHERE clause search conditions, and then the HAVING clause search conditions. Inner joins can be specified in either the FROM or WHERE clause without affecting the final result.
您还可以在执行查询之前使用SET SHOWPLAN_ALL ON
来显示查询的执行计划,以便衡量两者的性能差异。
查询处理阶段的逻辑顺序是:
FROM
- 包括JOIN
sWHERE
GROUP BY
HAVING
SELECT
ORDER BY
即使在 JOIN
或 WHERE
子句中也可以有任意多个条件。喜欢:
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 ....
查询处理的概念顺序是:
1. FROM
2. WHERE
3. GROUP BY
4. HAVING
5. SELECT
6. ORDER BY
但这只是概念上的顺序。事实上,引擎可能会决定重新排列条款。这是证据。让我们制作 2 个表,每个表有 1000000 行:
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
现在 运行 2 个查询:
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
请注意,第一个查询会在 join
条件中过滤掉大部分行,但第二个查询会在 where
条件中过滤掉。查看生成的计划:
1 TableScan - Predicate:[Test].[dbo].[test2].[id] as [t2].[id]=(100)
2 TableScan - Predicate:[Test].[dbo].[test2].[id] as [t2].[id]=(1)
这意味着在优化的第一个查询中,引擎决定首先评估 join
条件以过滤掉行。在第二个查询中,它首先计算 where
子句。
你可以参考这个join optimization
SELECT * FROM T1 INNER JOIN T2 ON P1(T1,T2)
INNER JOIN T3 ON P2(T2,T3)
WHERE P(T1,T2,T3)
嵌套循环连接算法将按以下方式执行此查询:
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;
}
}
}
}
如果您是为了 logical query processing
的问题来到本站,您确实需要阅读 this article on ITProToday by Itzik Ben-Gan。
Figure 3: Logical query processing order of query clauses
1 FROM
2 WHERE
3 GROUP BY
4 HAVING
5 SELECT
5.1 SELECT list
5.2 DISTINCT
6 ORDER BY
7 TOP / OFFSET-FETCH