web-dev-qa-db-ja.com

ビューにWHERE句を追加すると、ビューは最適化されますか?

ビューの内部または外部でビューをフィルタリングすると、違いがありますか?

たとえば、これら2つのクエリに違いはありますか?

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

または

SELECT Id
FROM MyView
WHERE SomeColumn = 1

そしてMyViewは次のように定義されます

SELECT Id, SomeColumn
FROM MyTable

ソーステーブルがリンクサーバーにある場合、答えは異なりますか?

リンクサーバーから大きなテーブル(44mil行)に2回クエリを実行し、結果の集計を取得する必要があるので、私は尋ねています。データにアクセスするために、クエリごとに1つずつ、2つのビューを作成する必要があるのか​​、それとも1つのビューとWHERE句で済むのかを知りたいです。

30
Rachel

これら2つの選択肢の間で、計画やパフォーマンスに違いはまったく見られないはずです。ビューが照会されると、ビューはベーステーブルに対するクエリに展開されます。つまり、同じシークまたはスキャンが使用されます。

これで、MyColumnのデータ型と選択性に応じて、ベーステーブルにフィルター処理されたインデックスを作成する場合(SQL Server 2008+に移動したとき)、パフォーマンスが向上する可能性がありますが、これでも再びビューを介してもしなくても違いはありません。

14
Aaron Bertrand

以下は、違いがないことを示す簡単な例です。データベースはAdventureWorksデータベースです。

2つのビューの定義:

create view Person.vContactWhere
as

    select *
    from person.Contact
    where ContactID = 24

go

create view Person.vContactNoWhere
as

    select *
    from person.Contact

go

これが最初のクエリで、WHERE句がビュー定義に含まれています。

select *
from person.vContactWhere

実行計画は次のとおりです。

enter image description here

また、2番目のクエリでは、ビュー定義ではなくWHERE句を使用してSELECT句を指定しています。

select *
from person.vContactNoWhere
where ContactID = 24

ここにその実行計画があります:

enter image description here

これらの実行プランからわかるように、これらは同じであり、同じ結果になります。このタイプのロジック/デザインが異なる結果を出力する状況は知りません。だから私はあなたがどちらの方法でも安全であり、個人的な好み(またはショップの手順)で行くと喜んで言いたいと思います。

6
Thomas Stringer

whatI'mreading に基づいて、SQLは実行プランを決定するときにサブクエリのような標準ビューを使用します。

したがって、私のクエリ例を使用して、

SELECT Id
FROM MyView
WHERE SomeColumn = 1

ここで、MyViewは次のように定義されています

SELECT Id, SomeColumn
FROM MyTable

同じ実行プランを生成する必要があります

SELECT Id
FROM 
(
    SELECT Id, SomeColumn
    FROM MyTable
) as T
WHERE SomeColumn = 1

ただし、この実行プランは、生成されるものとは異なる場合があります

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

この回答がインデックス付きビューと同じかどうかはわかりません

2
Rachel