13

Visual Studio 2010データベースプロジェクトのコード分析ルールSR0007には、次のように記載されています。

ISNULL関数でNULL値を含む可能性のある各列をラップすることにより、比較式でNULL値を処理する方法を明示的に示す必要があります。

ただし、次の場合、コード分析ルールSR0006に違反します。

比較の一部として、式に列参照が含まれています...列参照を含む式を比較する場合、コードによってテーブルスキャンが発生する可能性があります。

これはISNULLにも当てはまりますか、それともISNULLがテーブルスキャンを引き起こすことはありませんか?

4

1 に答える 1

20

はい、テーブルスキャンが発生します。(ただし、列が実際にnull可能でない場合は最適化されているようです)

SR0007 ルールは、述語を検索不能にし、列のインデックスが役に立たなくなることを意味するため、非常に不適切な包括的なアドバイスです列にインデックスがなくても、カーディナリティの見積もりが不正確になり、計画の他の部分に影響を与える可能性があります。

Microsoft.Performanceクエリのパフォーマンスを理解していない人が書いたように見えるので、カテゴリでの分類は非常に面白いです。

主張する根拠は

コードで 2 つの NULL 値または NULL 値を他の値と比較すると、コードは不明な結果を返します。

式自体はunknownコードに評価されますが=<>, >,などをevaluate asと<比較すると、式が に評価される行のみが返されることを理解すると、完全に決定論的な結果が返されます。NULLUnknownWHEREtrue

ANSI_NULLSifがオフになっていることを意味している可能性がありますが、 WHERE ISNULL([c2],0) > 2;vsのドキュメントに記載されている例は、WHERE [c2] > 2;とにかくこの設定の影響を受けません。この設定

比較のオペランドの 1 つが NULL またはリテラル NULL の変数である場合にのみ、比較に影響します。

スキャンとシーク以下を示す実行計画

CREATE TABLE #foo
  (
     x INT NULL UNIQUE
  )

INSERT INTO #foo
SELECT ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM   sys.all_columns

SELECT *
FROM   #foo
WHERE  ISNULL(x, 10) = 10

SELECT *
FROM   #foo
WHERE  x = 10

SELECT *
FROM   #foo
WHERE  x = 10
        OR x IS NULL 

ここに画像の説明を入力

于 2011-09-19T13:35:57.677 に答える