1

この Table.Column = @Param OR @Param IS NULL のような条件を使用する場合の WHERE 句では、列に INDEX を使用しません。

それは本当ですか、そうであれば、INDEXも使用するこの種のクエリを作成する方法

クエリの例

SELECT Col1, Col2 ...
FROM Table
WHERE (Col1 = @col OR @col IS NULL)
AND   (Col2 = @col2 OR @col2 IS NULL)
AND   (Col3 = @col3 OR @col3 IS NULL)

どんな助けでも。

4

4 に答える 4

5

残念ながら、実行計画の生成は期待どおりに動作しません。

その 1 つのクエリに対して、1 つのプランが作成されます。その計画を作成する際に、使用するインデックスが選択され、固定されます。どのパラメーターを指定しても、同じプラン、同じインデックスなどが常に使用されます。

otpimiser は、すべての不測の事態に適合できる最適な計画を見つけようとしましたが、このタイプのクエリの性質上、1 つもありません。インデックスを一切使わないプランだからこそ生まれる特徴。


解決策は、動的 SQL を使用することです。これは乱雑に感じますが、パラメータ化されたクエリをsp_executesqlで使用すると、実際には非常に構造化され、非常にパフォーマンスが高くなる可能性があります。

このテーマに関する非常に役立つ記事へのリンクは次のとおりです: 動的検索

非常に詳細ですが、この問題に対する非常に堅牢なアプローチです。

于 2012-05-30T12:17:57.233 に答える
0
SELECT Col1, Col2 ...
FROM Table
WHERE EXISTS(
    SELECT Col1, Col2, Col3
    INTERSECT
    SELECT @col, @col2, @col3)

直感的には、これはパフォーマンスが非常に悪いように見えますが、SQL Server のクエリ オプティマイザーはINTERSECT特別な処理を行う方法を知っており、内部的に (疑似 SQL) に変換します。

SELECT Col1, Col2 ...
FROM Table
WHERE (Col1, Col2, Col3) IS (@col, @col2, @col3)

クエリプランでわかるように。これらの列にインデックスがある場合、それらは使用でき、使用されます。

私はもともとこれを Paul White のUndocumented Query Plans: Equality Comparisonsブログ投稿から取り上げました。

于 2014-07-25T10:15:41.363 に答える
-1

これを試してみませんか:

SELECT Col1, Col2 ...
FROM Table
WHERE Col1 = IsNull(@col,Col1)
AND Col2 = IsNull(@col2,Col2)
AND Col3 = IsNull(@col3,Col3)

あなたの質問について: あなたのクエリ アナライザーは、 column1,2,3 のインデックスを使用しないと言っていますか? 3 つの列すべてのインデックスを作成しましたか? 次に、他に関係なく使用する必要がありますOR IS NULL

于 2012-05-30T12:17:18.073 に答える
-1

すべての where 句の列にインデックスを作成し、以下に示すように、より構造化されたクエリを使用してみてください。

SELECT Col1, Col2 ... 
FROM Table 
WHERE Col1 = **COALESCE**(@col,Col1)
AND Col2 = **COALESCE**(@col2,Col2)
AND Col3 = **COALESCE**(@col3,Col3)

COALESCE() 関数は、NULL 以外の最初の引数を返すため、STATUS が NULL の場合は '' を返します。

于 2012-05-30T13:07:50.830 に答える