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条件をどのように実行できますか?
クエリ処理の概念的な順序は次のとおりです。
1. FROM
2. WHERE
3. GROUP BY
4. HAVING
5. SELECT
6. ORDER BY
しかし、これは概念的な順序にすぎません。実際、エンジンは句を再配置することを決定する場合があります。これが証明です。それぞれ1000000行の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
次に、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
条件でほとんどの行をフィルターで除外し、2番目はwhere
条件でフィルターで除外することに注意してください。作成された計画を見てください。
1 TableScan-述語:[Test]。[dbo]。[test2]。[id] as [t2]。[id] =(100)
2 TableScan-述語:[Test]。[dbo]。[test2]。[id] as [t2]。[id] =(1)
つまり、最初のクエリでは、optimizedは最初にjoin
条件を評価して行を除外することを決定し、次にwhere
句を最初に評価しました。
クエリ処理フェーズの論理的な順序は次のとおりです。
FROM
-JOIN
sを含むWHERE
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
を使用してクエリの実行プランを表示し、2つのクエリのパフォーマンスの違いを測定することもできます。
あなたはこれを参照することができます 結合最適化
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
に関する質問のためにこのサイトにアクセスした場合は、 ITziTok-GanによるITProTodayに関するこの記事 を必ず読む必要があります。
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