2

質問から何を意味するのかが明確でない場合に備えて、この質問の後に完全な例を示しました。

約5つのテーブルのデータを結合するビューを作成しました。テーブルには膨大な量のデータがあり、クエリの実行には時間がかかります。私の質問は、私がそうする場合:

SELECT * FROM myView WHERE PersonID = 1000 

SQL Serverは「私が何を意味するのかを知っており」、その条件をビューの基になる結合に自動的に伝播しますか?すべての人に実行されるわけではありませんが、適切な段階で結果セットを最小限に抑えるようにします。それとも、すべてに対して実行さWHERE ID = 1000れ、完全な結果セットに対して実行されますか?


私が言っていることを単純化するために(...うまくいけば)、これが疑似TSQLシナリオの例です:

TABLE People (
    ID,
    Surname,
    DOB
)
TABLE Activities (
    ID,
    TypeID,
    LocationID,
    Date
)
TABLE PersonActivityInvolvements (
    ID, 
    PersonID, 
    ActivityID
)
TABLE ActivityTypes (
    ID,
    Name
)
TABLE Locations (
    ID,
    Street,
    City
)

Peopleだから私は私にすべて、Activities彼らが関わったもの ActivityType、そしてLocationそれが起こったことを示すビューが欲しいのです。この設定はそれほど複雑ではありませんが、各エンティティが数万と言われると、実行に非常に長い時間がかかる可能性があることがわかります。

ビューは次のようになります。

SELECT 
    *
FROM 
    People LEFT OUTER JOIN PersonActivityInvolvement PA
    ON People.ID = PA.ID
        INNER JOIN Activity 
        ON PA.ID = Activity.ID
            INNER JOIN ActivityTypes AT
            ON A.TypeID = AT.ID
                INNER JOIN Locations 
                ON A.LocationID = Locations.ID

だから

SELECT * FROM myView WHERE DOB >= dateAdd(YEAR, -18, getDate())

ビュー内のクエリはすべてのユーザーに対して実行されますか、それともSQL ServerはそれをPeople.DOBフィールドに適用する必要があることを認識しますか?

4

3 に答える 3

3

これは、述語プッシュと呼ばれます。

SQL Serverは一般的にこれに優れていますが、問題が発生している構造もいくつかあります(たとえば、この記事の最後の部分を参照してください)。

実行プランをチェックして、述語が適用される場所を確認してください。

于 2011-08-24T22:45:47.570 に答える
3

通常、オプティマイザはこれをaplombで処理しますが、クエリと暗黙のサブクエリがますます複雑になるにつれて、オプティマイザが適切な実行パスを選択する可能性はそれに応じて減少します。これは、テーブルにさらに多くのインデックスを設定するか、調査するテーブルに非常に類似したインデックスを作成することで悪化する可能性があります。

原則として、ビューへの参加はお勧めしません。また、他のビューで構成されるビューを作成することはお勧めしません。

于 2011-08-24T22:51:20.413 に答える
1

エンジンは、最速だと思うことは何でもします。そのフィールドにインデックスが付けられていて、JOINキーがすべてインデックス付けされている場合、最初にそのフィルターが実行される場合と実行されない場合があります。

WHERE句がより高価な場合(つまり、インデックスが作成されていない場合)、実際にはフィルターLASTを実行する可能性があります。そのようにすると、高価な操作が最小の結果セットで実行されます。

確実に知る唯一の方法は、クエリを実行して実行プランを確認することです(実際は推定されていません)。

于 2011-08-24T22:47:01.697 に答える