2012-03-29 7 views
1

私は、ジョインのコレクションであるビューを持っています。この質問の目的のために、私は以下のように見解を簡略化する。注:がプライマリキーで、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が最後のクエリに似た実行計画を使用して最適化するように、ビューを定義する方法はありますか?

ありがとうございます。

+2

最後のクエリは* UNIONが重複を排除するため*同等*ではありません - あなたのテストデータ*に重複はありません*と推測していますが、これは一般的に安全な前提ではありません。 –

+0

@Damien_The_Unbeliever:良いキャッチ。私は重要な部分を中止した。 'GROUP BY'です。 – Kuyenda

答えて

0

WHERE ... OR ...は、UNIONとは異なるクエリです。単一の行がColumn1xyzの値がabcである場合、にはWHERE ... OR ...の場合は1行だけ、UNIONの場合は2行しか生成されません。 UNIONは重複を取り除いていると主張するかもしれませんが(UNION ALLではありません)、これは投影されている他の列を省略した簡単な例です。しかし、この例のad-literamを検討しても、の2つの行の値は、Column1xyzの場合はColumn2となり、この場合、最初のクエリは2行、2番目のクエリは1を返します。間違っているために起こることができません。

+0

お詫び申し上げます。私は最初のクエリの重要な部分を中止しました。 'GROUP BY'節。ビューから照会するたびに、選択したすべての列を 'GROUP BY'して、離散レコードセットを取得します。 – Kuyenda

0

SQL Serverは、最後のクエリに似た実行計画を使用して2番目から最後のクエリを最適化しないのはなぜですか?

これは、提供した例に似た変換を行うことができます。あなたはRemusの答えに言及されている細部を理解する必要があります。私はそれが実行可能であることをかなり確信しています。たとえば、UNIONFULL OUTER JOINに書き換えることができます。これにより、適切な重複除外条件を挿入することができます。

この変換は2012年に実装されていません。これは残念ですが、製品チームは完璧なオプティマイザを提供できません。私たちが持っているものはかなり良いです。

SQL Serverが最後のクエリに似た実行計画を使用して最適化するようにビューを定義する方法はありますか?

これはわかりません。

この回答はあなたのために改善されないが、それは状況です。今のところ、インデックス付きのビューを作成することを検討してください。こうすることで、関心のある行のサブセットをあらかじめ生成することができます。複数の表の列にまたがる索引を作成できます。式のインデックスを付けることができます。