検索値がスワップされたときにパフォーマンスが著しく低下するデュアル自己結合クエリがあります。 "XYZ"検索値の順序によってSQLクエリのパフォーマンスが低下する
-- 500,000 i/o & 500ms execution
select
fooA.ID
, fooB.ID
from
foo AS fooA
INNER JOIN bar AS barA ON fooA.barID = barA.barID
INNER JOIN foo AS fooB ON fooA.fooID = fooB.fooID -- self join
INNER JOIN bar AS barB ON fooB.barID = barB.barID
where
barA.value = 'xyz'
AND barB.value = '60'
-- 5,000 i/o & 5ms execution
select
fooA.ID
, fooB.ID
from
foo AS fooA
INNER JOIN bar AS barA ON fooA.barID = barA.barID
INNER JOIN foo AS fooB ON fooA.fooID = fooB.fooID -- self join
INNER JOIN bar AS barB ON fooB.barID = barB.barID
where
barA.value = '60'
AND barB.value = 'xyz'
- 値は "バー" のテーブル15万回表示されます。
- 値「60」は「バー」テーブルに500回表示されます。
- 最初にリストされた検索値に応じて、最も内側のループが150,000行または500行を返すという点を除いて、クエリプランは同じです。
- 検索では、クラスタ化されていないインデックスの検索が実行されます。
- 両方のテーブルの統計がFULLSCANで更新されました。
なぜSQLクエリオプティマイザは、どちらのインスタンスでも、クエリプランの最も内側の結合が最小の行数である必要があることを正しく認識していませんか?
クエリの行数を常に最も制限する基準を使用します。それは一般的な経験則です。 – JonH
可能な答え:クエリパラメータ化、パラメータスニッフィング&プランの再利用。 –
fooテーブルとbarテーブルのIDを主キーにすることはできますか? –