web-dev-qa-db-ja.com

SQLがインデックス付きビューを使用しないのはなぜですか?

SQL Serverの次のバージョンがあります。

Microsoft SQL Server 2014(SP3)(KB4022619)-12.0.6024.0(X64)Enterprise Edition(64ビット)on Windows NT 6.3(Build 9600:)(Hypervisor)

次のビューを作成しました

CREATE VIEW [dbo].[vwGroupsOfficesDependencies]
WITH SCHEMABINDING 
AS
SELECT        GC.IdGroup, COUNT_BIG(*) AS countBig, OD.IdOffice
FROM            dbo.Group AS GC INNER JOIN
                         dbo.GroupDependencies AS Gd ON GC.IdGroup = Gd.IdGroup INNER JOIN
                         dbo.OfficeDependencies AS OD ON OD.IdDependency = Gd.IdDependency INNER JOIN
                         dbo.Dependencies AS D ON D.IdDependency = Gd.IdDependency
WHERE        (D.Active = 1)
GROUP BY GC.IdGroup, OD.IdOffice

次に、クラスター化インデックスを作成しました

CREATE UNIQUE CLUSTERED INDEX [IX_vwGroupsOfficesDependencies_IdOficeIdGroup] ON [dbo].[vwGroupsOfficesDependencies]
(
    [IdGroup] ASC,
    [IdOffice] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)

しかし、クエリを実行すると

SELECT IdGroup, IdOffice FROM dbo.[vwGroupsOfficesDependencies]

実行プランで、インデックス付きビューを使用していないことがわかります。ビュー内のテーブルとの結合を実行します。しかし、ヒントWITH(NOEXPAND)を含めると、インデックス付きビューが使用されます。 Enterprise以外のバージョンではWITH(NOEXPAND)を含める必要があると読みましたが、私の場合は必要ありません。 indexexビューを使用しないのはなぜですか?

6
Francisco G

NOEXPANDヒントを使用しない限り、SQL Serveralwaysは、最適化が始まる前に、基になるストアドクエリへのビュー参照を拡張します。

それmayは、後で最適化プロセスの1つ以上のインデックス付きビューに戻って、計画の一部または全体を一致させることを選択しました。

元の展開が後で元に戻されない一般的な理由は2つあります。

  1. 以前のオプティマイザアクティビティによって計画ツリーが変更され、インデックス付きビューが一致しなくなった(または、少なくとも、オプティマイザが使用できるツールで一致しなくなった)。
  2. オプティマイザは、インデックス付きビューの代替を探す前に、十分な(推定コストが低い)プランを見つけます。

NOEXPANDヒントを好む理由は他にもあります。たとえば、統計情報は、そのヒントが存在する場合にのみ、インデックス付きビューで自動的に作成されます。詳細については、私の記事 エンタープライズ版でNOEXPANDヒントを使用する別の理由 を参照してください。

14
Paul White 9