私は、ジョインのコレクションであるビューを持っています。この質問の目的のために、私は以下のように見解を簡略化する。注:がプライマリキーで、Table2.Table1ID
が外部キーです。それは私が私のコードで行う必要が参加するの数を減らし、それがSQL Serverがより効率的に参加し最適化することができますので、この目的のためにビューを使用してSQL Serverビュー実行計画:WHEREまたはUNIONと同じですか?
CREATE VIEW [View1] AS
SELECT t1.Column1, t2.Column2
FROM Table1 t1
JOIN Table2 t2 ON t1.Table1ID = t2.Table1ID
いいです。例えば:
SELECT Column1, Column2
FROM View1
WHERE Column1 = 'abc'
AND Column2 = 'xyz'
GROUP BY Column1, Column2
SQL Serverは、列1の値が「ABC」と列2の値が「XYZ」である表2からレコードのサブセットであり、表1からのレコードのサブセットのみを接合して上記のクエリを最適化します。つまり、SQL Serverの実行計画では、結合を適用する前にビュー内のそれぞれのテーブルにフィルタリングをスマートに適用し、結合で考慮する必要があるレコードの数を減らします。
、しかし、私はOR
オペレータにWHERE
句でAND
オペレータを変更することで、元のクエリを変更する場合は、実行計画は、結合を実行する前に、フィルタリングを適用ないを行います。
SELECT Column1, Column2
FROM View1
WHERE Column1 = 'abc'
OR Column2 = 'xyz'
GROUP BY Column1, Column2
上記のクエリの実行プランは、最初の表1と表2からすべてのレコードを結合して、where句秒を適用します。これは、テーブルが結合され、Column1とColumn2の両方の値が存在し、説明されるまで、OR
演算子テストを満たすことができないため、ブール論理に従います。
一方、次のクエリは、前のクエリと同じ結果セットを返します。
SELECT Column1, Column2
FROM View1
WHERE Column1 = 'abc'
UNION
SELECT Column1, Column2
FROM View1
WHERE Column2 = 'xyz'
後者の2つのクエリが同じ結果をもたらすが、二つの第二の参加をsppliedされる前に実行プランは、各SELECT
ステートメント内の各テーブルにwhere句を適用するようにSQL Serverによって最適化されますこのビューでは、結合されるレコードの数が少なくなります。ビューが実際に2回呼び出され、結果のレコードセットの共通部分がUNION
によって返されていても、全体的に効率的なクエリが得られます。
私の質問は以下のとおりです。
- 最後のクエリに似た実行計画を使用して、最後のクエリに2つ目のSQL Serverの最適化しないのはなぜ?
- SQL Serverが最後のクエリに似た実行計画を使用して最適化するように、ビューを定義する方法はありますか?
ありがとうございます。
最後のクエリは* UNIONが重複を排除するため*同等*ではありません - あなたのテストデータ*に重複はありません*と推測していますが、これは一般的に安全な前提ではありません。 –
@Damien_The_Unbeliever:良いキャッチ。私は重要な部分を中止した。 'GROUP BY'です。 – Kuyenda