ビューのインデックスの解決
インデックス付きビューは他のインデックスと同様、使用することにメリットがあるとクエリ オプティマイザで判断された場合にのみ、SQL Server でクエリ プランに使用されます。
インデックス付きビューは SQL Server のどのエディションでも作成できます。SQL Server Enterprise では、クエリ オプティマイザによる判断でインデックス付きビューが自動的に使用されます。その他のエディションでインデックス付きビューを使用するには、NOEXPAND テーブル ヒントを指定する必要があります。
SQL Server クエリ オプティマイザは、次の条件が満たされている場合にインデックス付きビューを使用します。
次のセッション オプションが ON である。
ANSI_NULLS
ANSI_PADDING
ANSI_WARNINGS
ARITHABORT
CONCAT_NULL_YIELDS_NULL
QUOTED_IDENTIFIER
NUMERIC_ROUNDABORT セッション オプションが OFF である。
クエリ オプティマイザにより、ビューのインデックス列とクエリ要素との間で、次のような項目の一致が検出される。
WHERE 句の検索条件の述語
結合操作
集計関数
GROUP BY 句
テーブル参照
クエリ オプティマイザが検討したアクセス方法の中で、インデックスを使用した場合の推定コストが最小である。
クエリ内で (直接、またはビューを展開して基になるテーブルにアクセスすることにより) 参照しているテーブルのうち、インデックス付きビュー内のテーブル参照に対応しているすべてのテーブルについて、クエリ内で適用されているヒントの組み合わせが同じである。
注 現在のトランザクション分離レベルにかかわらず、このコンテキストでは READCOMMITTED ヒントと READCOMMITTEDLOCK ヒントは常に異なるヒントと見なされます。
SET オプションおよびテーブル ヒントの要件を除くと、上記の条件は、テーブル インデックスがクエリをカバーするかどうかを判断するためにクエリ オプティマイザにより使用されるルールと同じです。クエリで他に何も指定しなくてもインデックス付きビューを使用できます。
クエリの FROM 句でインデックス付きビューを明示的に参照しなくても、インデックス付きビューが使用されます。ベース テーブル内の列に対する参照がクエリに含まれており、その参照がインデックス付きビューにも存在する場合、クエリ オプティマイザは、インデックス付きビューの使用によりアクセス コストを最小にできると推定できれば、インデックス付きビューを選択します。これはクエリ オプティマイザが、ベース テーブルのインデックスを、クエリ内で直接参照されていない場合に選択するのと同じ手法です。クエリ内で指定されている 1 つ以上の列をカバーするオプションとして最もコストが低ければ、クエリで参照されていない列がビューに含まれていても、クエリ オプティマイザがそのビューを選択することがあります。
クエリ オプティマイザは FROM 句で参照されているインデックス付きビューを標準のビューとして扱います。最適化処理の開始時には、ビューの定義をクエリにまで拡張します。そのうえで、インデックス付きビューの照合を実行します。オプティマイザが選択した最終的な実行プランでは、インデックス付きビューが使用されることも、ビューが参照するベース テーブルにアクセスすることにより、ビュー内の必要なデータが具体化されることもあります。いずれにしても、最もコストが低いプランが選択されます。
インデックス付きビューでのヒントの使用
EXPAND VIEWS クエリ ヒントを指定すると、ビューのインデックスがクエリで使用されるのを禁止できます。NOEXPAND テーブル ヒントを指定すると、クエリの FROM 句で指定したインデックス付きビューのインデックスを強制的に使用することができます。ただし、各クエリを使用するための最適なアクセス方法はクエリ オプティマイザによる動的な判断に任せることをお勧めします。EXPAND および NOEXPAND を使用するのは、テストの結果パフォーマンスの大幅な向上が示された場合のみにしてください。
EXPAND VIEWS オプションは、クエリ オプティマイザに対し、クエリ全体に関してビュー インデックスを使用しないことを指定します。
NOEXPAND をビューに対して指定した場合、ビューに定義されたインデックスを使用することがクエリ オプティマイザにより検討されます。オプションの INDEX() 句で NOEXPAND を指定すると、クエリ オプティマイザの判断で指定されたインデックスが強制的に使用されます。NOEXPAND はインデックス付きビューに対してのみ指定でき、インデックスのないビューには指定できません。
ビューを含んだクエリで NOEXPAND と EXPAND VIEWS のいずれも指定しない場合、基になるテーブルにアクセスするためにビューが拡張されます。ビューを構成するクエリにテーブル ヒントが含まれている場合、基になるテーブルにヒントが反映されます (この処理の詳細については、「ビューの解決」を参照してください)。ビューの基になるテーブルに存在するヒントのセットがテーブル間で同一であれば、クエリはインデックス付きビューと一致する可能性があります。ほとんどの場合、ヒントはビューから直接継承されるので双方のヒントは一致します。ただし、クエリの参照先がビューではなくテーブルであり、参照先テーブルに直接適用されているヒントがテーブルによって異なる場合、そのようなクエリはインデックス付きビューと一致しません。ビューの拡張後、INDEX、PAGLOCK、ROWLOCK、TABLOCKX、UPDLOCK、XLOCK のいずれかのヒントがクエリの参照先テーブルに適用される場合、クエリはインデックス付きビューと一致しません。
INDEX (index_val[ ,...n] ) という形式のテーブル ヒントでクエリ内のビューを参照しているときに、NOEXPAND ヒントを指定しない場合、インデックス ヒントは無視されます。特定のインデックスを使用するように指定するには NOEXPAND を使用します。
通常、インデックス付きビューがクエリに一致すると、クエリ内のテーブルまたはビューに指定したヒントが直接インデックス付きビューに適用されます。クエリ オプティマイザがインデックス付きビューを使用しないと判断した場合、ヒントはすべて、ビュー内で参照しているテーブルに直接伝達されます。詳細については、「ビューの解決」を参照してください。この伝達は、結合ヒントには当てはまりません。結合ヒントはクエリ内の元の場所でのみ適用されます。クエリ オプティマイザがクエリとインデックス付きビューを照合する際に、結合ヒントは無視されます。結合ヒントを含むクエリの一部に一致したインデックス付きビューがクエリ プランで使用される場合、その結合ヒントはプランに使用されません。
SQL Server 2008 のインデックス付きビューの定義ではヒントが許可されていません。互換性モードが 80 以上の場合、SQL Server はインデックス付きビューの定義の保守時にも、インデックス付きビューを使用したクエリの実行時にも、定義に含まれているヒントを無視します。互換性モード 80 では、インデックス付きビューの定義でヒントを使用しても構文エラーにはなりませんが、ヒントは無視されます。