ストアドプロシージャを使用します。
WHERE句では、ほとんどの入力がデフォルトでNullになっていることをクエリオプティマイザーが認識しているため、短絡(OR)を使用して実行を高速化します。これにより、クエリを柔軟かつ高速にすることができます。
WHERE句にテーブル値パラメーターを追加しました。レポートの実行時間は150ミリ秒から450ミリ秒に増加し、読み取りは70,000から200,000になりました。
...
WHERE
--Integer value parameters
AND ((@hID is Null) OR (h.ID = @hID))
AND ((@dID is Null) OR (d.ID = @dID))
AND ((@mID is NULL) OR (m.ID = @mID))
--New table value parameter
--Execute, Processing time and read's increased.
--No additional JOIN added.
AND (NOT EXISTS (SELECT Null FROM @rIDs) OR r.ID IN (SELECT r FROM @rIDs))
NOT EXISTSを短絡したり、このクエリを高速化するにはどうすればよいですか?クエリを実行する前に、BIT値を追加し、行がテーブル値パラメーターに含まれているかどうかを確認してみました。私が見つけた唯一の方法は、2つのクエリを実行し、一方を他方に対して実行することです。大量のクエリを変更したり、複数のテーブル値パラメーターをミックスに追加したりする必要がある場合は、あまり良くありません。
前もって感謝します。
編集:
テーブル値パラメーターの比較:
AND (NOT EXISTS (SELECT Null FROM @rIDs) OR r.ID IN (SELECT r FROM @rIDs))
および整数パラメータ:
AND ((@rID) OR (r.ID = @rID))
TVPを0行、整数パラメーターをnullでコンパイルした後、同様の実行速度を示しました。クエリオプティマイザーが正しいマナーで短絡していて、以前の比較が正しくなかったと思います。実行計画では、上記のコストを55%と45%に分割しますが、これは許容範囲です。TVPの行数が増えても分割は変わりませんが、ディスクから読み取る必要のあるページが増えるため、レポートの生成にかかる時間が長くなります。面白い。