クラスタ化インデックスによってテーブル内のレコードをルックアップするために使用されるビューがあります。このビューには、selectステートメントに2つのサブクエリがあり、クラスター化インデックスによって2つの大きなテーブルのデータをルックアップします。
非常に単純化すると、次のようになります。
SELECT a,
(SELECT b FROM tableB where tableB.a=tableA.a) as b
(SELECT c FROM tableC where tableC.a=tableA.a) as c
FROM tableA
[tableB]へのほとんどのルックアップは、[tableB]の非クラスター化インデックスを正しく使用し、非常に効率的に機能します。ただし、SQL Serverが実行プランを生成する際に、渡される値を含まない[tableB]のインデックスを使用することが非常にまれです。したがって、上記の例に従って、列[a]のインデックスはtableBに存在しますが、プランは代わりに列[z]を持つクラスター化インデックスのスキャンを実行します。SQL独自の言語を使用すると、プランの「述語はオブジェクトに関連しません」。なぜこれが実用的であるのかわかりません。その結果、SQLがこれを行う場合、インデックス内のすべてのレコードをスキャンする必要があります。これは、SQLが存在しないため、最大30秒かかるためです。いつも、それは明らかに間違っているようです。
実行計画が決して正しくないように見える何かをするところで、これを以前に見た人はいますか?とにかくクエリを書き直すつもりなので、私の懸念はクエリの構造ではなく、SQLがなぜそれを間違ってしまうのかということです。
SQL Serverは、一度機能したプランを選択でき、データセットが変更されると非効率になることがありますが、この場合は機能しません。
さらに詳しい情報
- [tableB]には400万件のレコードがあり、[a]のほとんどの値はnullです。
- プランを生成した最初のクエリを取得できません
- これらのクエリはColdfusionを介して実行されますが、現時点では、SQLServerでこれを個別に見た人に興味があります。