哪个子句在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的条件下表现更好?
查询处理的概念顺序是:
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 - 谓词:[测试]。[dbo]。[test2]。[id]为[t2]。[id] =(100)
2 TableScan - 谓词:[测试]。[dbo]。[test2]。[id] as [t2]。[id] =(1)
这意味着在第一个查询优化时首先决定评估join
条件以过滤掉行,然后在第二个中首先评估where
子句。
查询处理阶段的逻辑顺序是:
FROM
- 包括JOIN
sWHERE
GROUP BY
HAVING
SELECT
ORDER BY
你甚至可以在你的JOIN
s或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 ....
你可以参考MSDN
查询选择的行首先由FROM子句连接条件过滤,然后是WHERE子句搜索条件,然后是HAVING子句搜索条件。可以在FROM或WHERE子句中指定内部联接,而不会影响最终结果。
您还可以在执行查询之前使用SET SHOWPLAN_ALL ON
来显示查询的执行计划,以便您可以测量两者中的性能差异。
你可以参考这个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