2

WHERE 句で OR を使用して、コンパイル中に UNION を使用して 2 つのクエリに分割するクエリを取得するにはどうすればよいですか? 手動で書き直すと、UNION を使用したクエリは、単一のクエリよりも 100 倍高速になります。これは、ユニオンの各クエリで異なるインデックスを効果的に使用できるためです。オプティマイザにこのアプローチを使用させる方法はありますか?

次のようなクエリがあります。

select columnlist
from table1
join table2 on joincond2
join table3 on joincond3
where conditions1 
    and ((@param1 is null and cond3a) or (cond3b))

ここで、columnlist、joincond2、joincond3、および conditions1 はすべて長い式です。キッカーは、OR の条件の 1 つだけが真になることです。

最初はユニオンを実行するように書き直せると思っていましたが、columnlist、joincond2、joincond3、および conditions1 を繰り返しています。これは、将来多くのメンテナンスが必要になる可能性のある 20 行ほどの SQL 行です。私が提供できるヒントや、WHERE句を書くためのより良い方法はありますか? 前もって感謝します。

4

2 に答える 2

4

グループ化できます

select columnlist
from table1
join table2 on joincond2
join table3 on joincond3

ビューに追加してから、union を使用します。

ただし、sql2005/8 に移行できれば、共通テーブル式を使用できます。

with cte ( columnlist )
as (
    select columnlist
    from table1
    join table2 on joincond2
    join table3 on joincond3 )
select columnlist from cte where ...
union
select columnlist from cte where ...
于 2008-12-16T19:18:24.093 に答える
0

クエリにOPTION(RECOMPILE)を追加してみてください。ストアドプロシージャにある場合は、それにWITHRECOMPILEも追加します。クエリを最初に実行すると、SQL Serverがプランを作成してキャッシュしますが、2回目は、古い(現在は貧弱な)クエリプランを使用している可能性があります。

クエリを使用するたびに再コンパイルする必要があるため、マイナーヒットが発生しますが、不十分なプランを使用する場合に比べるとごくわずかです。

編集:SQL2000のストアドプロシージャでWITHRECOMPILEを使用すると、常に正しく機能するとは限らないことを読みました。このバグはSQL2005で修正されたと思われますが、個人的にバグに遭遇したことはないので、正確な対処方法はわかりません。でも試してみてください。

于 2008-12-16T19:33:22.317 に答える