通常、入力引数または列が引数と等しい場合、次のような式が頭に浮かぶという結果を選択するケースに遭遇しました。
WHERE @Arg IS NULL OR Name = @Arg
@Arg
が に設定されている場合、ほとんどすべてのプログラミング言語は 2 番目の条件を無視しNULL
ます。ただし、SQL Server での実行が非常に遅く、2 番目の条件が常に実行されているように見えました。
誰か助けてくれませんか?
通常、入力引数または列が引数と等しい場合、次のような式が頭に浮かぶという結果を選択するケースに遭遇しました。
WHERE @Arg IS NULL OR Name = @Arg
@Arg
が に設定されている場合、ほとんどすべてのプログラミング言語は 2 番目の条件を無視しNULL
ます。ただし、SQL Server での実行が非常に遅く、2 番目の条件が常に実行されているように見えました。
誰か助けてくれませんか?
これはブール値のショート サーキット ( SQL では保証されていません。SQL Server のブール演算子のショート サーキットについてを参照) の問題ではなく、コンパイルの問題です。SQL Server はクエリ プランをコンパイルする必要があり、そのプランはの任意の値に対して@Arg
機能する必要があります。この要件により、考えられる多くの最適化が排除され (たとえば、インデックスName
が使用できない場合)、クエリが不必要に遅くなります。
このパターンは通常、検索フォームで何度も繰り返されるため、別のクエリを作成することをお勧めします。根本的な問題は、同じ呼び出しを使用して異なることを行う (名前による検索、ID による検索など) 不適切な API 設計です。
マーティンによってリンクされた記事は、さまざまなアプローチの長所と短所を説明しています。Erland のアドバイスはより微妙です (単純なケースには IF を使用し、複雑なケースには動的 SQL を使用します) が、要するに同じことです:ハードコード ( s) かコード生成 (動的 SQL)かにかかわらず、ケースごとに異なるクエリを使用します。IF