0

例に直接向かいましょう:

クエリ1:

Select * 
Into #temp_v1 
From View1

Select * 
Into #temp_v2
From View2

select *
From #temp_v1 v1
where not exists (
    Select * From #temp_v2 where key = v1.key
)

これはよりもはるかに高速です

クエリ2:

select *
From View1 v1
where not exists (
    Select * From View2 where key = v1.key
)

さて、明らかに、私は例を単純化しました。View1はビューのビューであり、結合の使用を困難にするためにさらに多くの比較が必要です。

私の質問は、SQLをどのように書くべきかということではなく、SQL Serverがクエリ1を3秒で実行し、クエリ2を10分で実行できるようになる理由です。

さらに重要なのは、クエリ1のような実行プランを作成するためにオプティマイザーに提供できる魔法のオプションがあります。

4

1 に答える 1

1

ビューが複雑な場合、ビューへのアクセスは操作の最も遅い部分であり、クエリ 1 はそれを最小限に抑えます。

各ビューに 1,000,000 行があるとします。クエリ 1 では、ビューから 2,000,000 回だけ行を取得していますが、クエリ 2 では、5 億回以上ビューから行を取得する可能性があります。(最良のシナリオでは、すべてv1.keyがビュー 2 に存在します。ただし、それを確認するために、毎回ビュー 2 の約半分の行をチェックする必要があります)。

SQLサーバーの実行計画についてはわかりませんが、次のようなクエリを書くとより効率的になります。

with keys as (
   select key from View2
)
select *
From View1 v1
where not exists (
    Select * From keys where key = keys.key
)

事前にビュー 2 からすべてのキーを取得することで、基本的にクエリ 1 と同じ効率が得られ、一時テーブルの手順は不要です。

于 2012-10-19T12:09:49.700 に答える