5

検索値が交換されるとパフォーマンスが大幅に低下するデュアル自己結合クエリがあります。

-- 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'
  • 値「xyz」は、「バー」テーブルに150,000回リストされています。
  • 値「60」は「バー」テーブルに500回リストされています。
  • クエリプランは同じですが、最も内側のループが最初にリストされている検索値に応じて150,000行または500行を返す点が異なります。
  • 検索は、非クラスター化インデックスでシークを実行します。
  • 統計は、FULLSCANを使用して両方のテーブルで更新されました。

SQLクエリオプティマイザが、両方のインスタンスでクエリプランの最も内側の結合が行数が最も少ない結合であることを正しく識別しないのはなぜですか?

4

1 に答える 1

3

SQL Serverは、クエリが実行されるたびにクエリを再コンパイルするわけではありません。これは1回実行され、最初に表示される正確な値に最適化されます。不幸な計画がキャッシュされていると思います。

最後に追加OPTION (RECOMPILE)してみてください。

于 2012-05-15T18:46:34.150 に答える