Moh*_*aRS 15 sql sql-server select join where
哪个子句在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
Run Code Online (Sandbox Code Playgroud)
是否,首先它检查WHERE子句然后执行INNER JOIN
先JOIN检查条件?
如果它首先执行JOIN然后WHERE条件; 如何在不同JOIN的条件下执行更多的条件?
Gio*_*uri 19
查询处理的概念顺序是:
1. FROM
2. WHERE
3. GROUP BY
4. HAVING
5. SELECT
6. ORDER BY
Run Code Online (Sandbox Code Playgroud)
但这只是一个概念性的顺序.事实上,引擎可能会决定重新安排条款.这是证据.让我们制作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
Run Code Online (Sandbox Code Playgroud)
现在运行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
Run Code Online (Sandbox Code Playgroud)
注意首先会在join条件中过滤大多数行,在条件下过滤第二行where.看看生产计划:
1 TableScan - 谓词:[测试].[dbo].[test2].[id]为[t2].[id] =(100)
2 TableScan - 谓词:[测试].[dbo].[test2].[id] as [t2].[id] =(1)
这意味着在第一个查询优化中首先决定评估join条件以过滤掉行,在第二个它where首先评估子句.
查询处理阶段的逻辑顺序是:
FROM- 包括JOINsWHEREGROUP BYHAVINGSELECTORDER 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 ....
Run Code Online (Sandbox Code Playgroud)
小智 6
可以参考这个join优化
SELECT * FROM T1 INNER JOIN T2 ON P1(T1,T2)
INNER JOIN T3 ON P2(T2,T3)
WHERE P(T1,T2,T3)
Run Code Online (Sandbox Code Playgroud)
嵌套循环连接算法将按以下方式执行此查询:
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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18273 次 |
| 最近记录: |