11

値に一致する測定値を持つレコード、またはその測定値がまったくないレコードを見つける必要があるという問題があります。私はその問題を 3 つまたは 4 つの異なるアプローチで解決しJOINましNOT INNOT EXISTS。ただし、クエリは毎回非常に遅くなりました。次に、クエリを 2 つに分割してみましたが、どちらも非常に高速 (3 秒) に実行されました。ただし、 を使用してクエリを組み合わせると、OR5 分以上かかります。

UNIONこれは非常に高速ですが、使用しているスクリプトには非常に不便です。

2つの質問:

  1. なぜUNIONそんなに速いのですか?(または、なぜORそんなに遅いのですか)?
  2. 高速なステートメントにMSSQL別のアプローチを 強制的に使用する方法はありますか?OR
4

2 に答える 2

14

その理由は、クエリで を使用ORすると、クエリ オプティマイザーがインデックス シークの使用を放棄し、スキャンに戻ることがよくあるためです。OR2 つのクエリの実行計画を見ると、 を使用している場所ではスキャンが行われ、 を使用している場所ではシークが行われている可能性が高いでしょうUNION。クエリを見なければ、条件を再構築する方法についてアイデアを提供することは実際には不可能ですOR. ただし、行を一時テーブルに挿入して結合すると、良い結果が得られる場合があります。

また、行一致のコストを取り除くため、すべての結果が必要な場合UNION ALLよりも、通常は使用することをお勧めします。UNION

于 2013-03-12T13:09:07.617 に答える
5

現在、SQL Server には、ステートメントが使用されUNIONていない場合に実行計画を強制する方法はありません。UNION2 つの部分の唯一の違いがWHERE句である場合は、複雑なクエリを使用してビューを作成します。UNIONクエリは非常に単純になります。

SELECT * FROM dbo.MyView WHERE <cond1>
UNION ALL
SELECT * FROM dbo.MyView WHERE <cond2>

UNION ALL可能な限り、このコンテキストで使用することが重要です。SQL Server を使用するだけの場合UNION、重複する行を除外する必要があり、ほとんどの場合、コストのかかる並べ替え操作が必要になります。

于 2013-03-12T13:08:06.840 に答える