これは絶対的な正解ではありませんが、SQL Fiddleに示されているネストされたループのクエリプランでは、USE PLAN
ヒントを使用してクエリ2からクエリ1にプランを適用できたが、逆の操作を試みると失敗しました。
USE PLANヒントにクエリに対して正当であると確認できなかったプランが含まれているため、クエリプロセッサはクエリプランを作成できませんでした。USE PLANヒントを削除または置き換えます。プランの強制が成功する可能性を最大限に高めるには、USE PLANヒントで提供されるプランが、同じクエリに対してSQL Serverによって自動的に生成されるものであることを確認してください。
オプティマイザ変換ルール ReorderLOJN
を無効にすると、以前成功した計画のヒントも成功しなくなります。
大量のデータを実験してみると、SQL Serverは確か(A LOJ B) LOJ C
にA LOJ (B LOJ C)
自然に変換できることを示していますが、その逆が真実であるという証拠はありませんでした。
最初のクエリのパフォーマンスが2番目のクエリよりも優れている非常に不自然なケースは、
DROP TABLE MyGrandChild , MyChild, MyParent
CREATE TABLE MyParent
(Id int)
CREATE TABLE MyChild
(Id int PRIMARY KEY
,ParentId int,
Filler char(8000) NULL)
CREATE TABLE MyGrandChild
(Id int
,ParentId int)
INSERT INTO MyChild
(Id, ParentId)
SELECT TOP (100000) ROW_NUMBER() OVER (ORDER BY @@SPID),
ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM master..spt_values v1, master..spt_values
INSERT INTO MyGrandChild
(Id, ParentId)
OUTPUT INSERTED.Id INTO MyParent
SELECT TOP (3000) Id, Id AS ParentId
FROM MyChild
ORDER BY Id
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
SELECT gc.Id AS gcId,
gc.ParentId AS gcpId,
c.Id AS cId,
c.ParentId AS cpId,
p.Id AS pId
FROM MyGrandChild AS gc
LEFT OUTER JOIN MyChild AS c
ON c.[Id] = gc.[ParentId]
LEFT OUTER JOIN MyParent AS p
ON p.[Id] = c.[ParentId]
SELECT gc.Id AS gcId,
gc.ParentId AS gcpId,
c.Id AS cId,
c.ParentId AS cpId,
p.Id AS pId
FROM MyGrandChild AS gc
LEFT OUTER JOIN( MyChild AS c
LEFT OUTER JOIN MyParent AS p
ON p.[Id] = c.[ParentId])
ON c.[Id] = gc.[ParentId]
それは計画を与える
私にとって、クエリ1の経過時間は108ミリ秒でしたが、クエリ2の経過時間は1,163ミリ秒でした。
クエリ1
Table 'Worktable'. Scan count 0, logical reads 0
Table 'MyChild'. Scan count 0, logical reads 9196
Table 'MyGrandChild'. Scan count 1, logical reads 7
Table 'MyParent'. Scan count 1, logical reads 5
クエリ2
Table 'MyParent'. Scan count 1, logical reads 15000
Table 'MyChild'. Scan count 0, logical reads 9000
Table 'MyGrandChild'. Scan count 1, logical reads 7
したがって、最初の(「ネストされていない」)構文は、より多くの潜在的な結合順序を検討できるため、潜在的に有益であると暫定的に想定されているかもしれませんが、これを一般的なルールとして十分に信頼できる十分なテストを行っていません。
クエリ2のパフォーマンスが向上するカウンターの例を考え出すことは完全に可能です。両方を試して実行プランを確認してください。