MainTable
600,000 レコードを少し超えるテーブル ( ) があります。JoinTable
親/子タイプの関係で、2 番目のテーブル ( ) を介してそれ自体に結合します。
SELECT Child.ID, Parent.ID
FROM MainTable
AS Child
JOIN JoinTable
ON Child.ID = JoinTable.ID
JOIN MainTable
AS Parent
ON Parent.ID = JoinTable.ParentID
AND Parent.SomeOtherData = Child.SomeOtherData
すべての子レコードに親レコードがあり、JoinTable のデータが正確であることはわかっています。
このクエリを実行すると、実行に文字通り数分かかります。ただし、Left Join を使用して親に参加すると、実行に 1 秒未満かかります。
SELECT Child.ID, Parent.ID
FROM MainTable
AS Child
JOIN JoinTable
ON Child.ID = JoinTable.ID
LEFT JOIN MainTable
AS Parent
ON Parent.ID = JoinTable.ParentID
AND Parent.SomeOtherData = Child.SomeOtherData
WHERE ...[some info to make sure we don't select parent records in the child dataset]...
INNER JOIN
anと aの結果の違いを理解していLEFT JOIN
ます。この場合、すべての子が親を持つため、まったく同じ結果が返されます。両方のクエリを実行すると、データセットを比較できますが、それらはまったく同じです。
LEFT JOIN
がよりもはるかに高速に実行されるのはなぜINNER JOIN
ですか?
UPDATEクエリプランをチェックし、内部結合を使用すると、親データセットから始まります。左結合を行う場合、子データセットから開始します。
使用するインデックスはすべて同じです。
常に子供から始めるように強制できますか? 左結合を使用するとうまくいきますが、それは間違っているように感じます。
同様の質問が以前にここで尋ねられましたが、私の質問に答えるものはないようです。
たとえば、 SQL Server の INNER JOIN と LEFT JOIN のパフォーマンスで選択された回答は、左結合は常に内部結合よりも遅いことを示しています。議論は理にかなっていますが、私が見ているものではありません。