哪个子句首先在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的条件下执行更多?
答案 0 :(得分:16)
查询处理的概念顺序是:
$('footer').css('height', '300px');
但这只是一个概念性的顺序。事实上,引擎可能会决定重新安排条款。这是证据。让我们制作2个表,每个表1000000行:
1. FROM
2. WHERE
3. GROUP BY
4. HAVING
5. SELECT
6. ORDER BY
现在运行2个查询:
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
注意首先会在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
条件下过滤第二行。看看制作的计划:
1 TableScan - 谓词:[测试]。[dbo]。[test2]。[id] as [t2]。[id] =(100)
2 TableScan - 谓词:[测试]。[dbo]。[test2]。[id] as [t2]。[id] =(1)
这意味着在优化的第一个查询中首先决定评估where
条件以过滤掉行,然后在第二个中首先评估join
子句。
答案 1 :(得分:8)
查询处理阶段的逻辑顺序是:
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 ....
答案 2 :(得分:3)
您可以参考MSDN
查询选择的行首先由FROM子句过滤 连接条件,然后WHERE子句搜索条件,然后 HAVING子句搜索条件。 可以在中指定内部联接 FROM或WHERE子句,不影响最终结果。
您还可以在执行查询之前使用SET SHOWPLAN_ALL ON
来显示查询的执行计划,以便您可以衡量两者的性能差异。
答案 3 :(得分:1)
您可以参考此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;
}
}
}
}
答案 4 :(得分:0)
如果您来到此网站来解答有关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