CTEを使用してビューにインデックスを付けることはできません。ビューが持つことができSCHEMABINDING
ますが。このように考えてください。ビューにインデックスを付けるには、2つの条件(および他の多くの条件)を満たしている必要があります。(a)ビューが作成されていることWITH SCHEMABINDING
、および(b)CTEが含まれていないことです。ビューをスキーマバインドするために、CTEが含まれていないという条件を満たす必要はありません。
ビューにCTEがあり、インデックスを作成することでメリットが得られるシナリオがあるとは思いません。これはあなたの実際の質問の周辺ですが、私の本能は、魔法のように高速化するためにこのビューにインデックスを付けようとしているということです。インデックス付きビューは、必ずしもベーステーブルに対するクエリよりも高速になるとは限りません。理由による制限があり、それらが意味をなす特定のユースケースのみがあります。すべてのビューを魔法の「高速化」ボタンとして盲目的にインデックス付けしないように注意してください。また、インデックス付きビューにはメンテナンスが必要であることを忘れないでください。そのため、ベーステーブルに影響を与えるワークロード内のすべてのDML操作のコストが増加します。
スキーマバインディングは、ビューのインデックス作成だけを目的としたものではありません。また、UDFなどで決定論を説得するために使用したり、ビューや関数で使用して基になるスキーマへの変更を防止したり、場合によってはパフォーマンスを向上させたりすることもできます(たとえば、UDFがスキーマにバインドされていない場合。オプティマイザは、基になるDDLの変更を処理するためにテーブルスプールを作成する必要がある場合があります)。したがって、ビューをスキーマバインドできるのにインデックスを作成できないのは変だと思わないでください。ビューのインデックスを作成するにはそれが必要ですが、関係は相互ではありません。
あなたの特定のシナリオのために、私はこれをお勧めします:
CREATE VIEW dbo.PatClassCounts
WITH SCHEMABINDING
AS
SELECT pat_id, drug_class,
COUNT_BIG(*) AS counts
FROM dbo.rx
GROUP BY pat_id, drug_class;
GO
CREATE UNIQUE CLUSTERED INDEX ON dbo.PatClassCounts(pat_id, drug_class);
GO
CREATE VIEW dbo.ClaimSums
WITH SCHEMABINDING
AS
SELECT pat_id,
SUM(c.std_cost) AS [Healthcare Costs],
COUNT_BIG(*) AS counts
FROM dbo.claims
GROUP BY pat_id;
GO
CREATE UNIQUE CLUSTERED INDEX ON dbo.ClaimSums(pat_id);
GO
これで、これら2つのインデックス付きビューを結合するだけのインデックスなしビューを作成でき、インデックスを利用します(NOEXPAND
下位エディションで使用する必要がある場合がありますが、不明です)。
CREATE VIEW dbo.OriginalViewName
WITH SCHEMABINDING
AS
SELECT p.pat_id, p.drug_class, p.counts, c.[Healthcare Costs]
FROM dbo.PatClassCounts AS p
INNER JOIN dbo.ClaimSums AS c
ON p.pat_id = c.pat_id;
GO
さて、これはすべて、この情報を事前に集約する価値があることを前提としています-このクエリを頻繁に実行しないが、データが大幅に変更される場合は、インデックス付きビューを作成しない方がよい場合があります。
また、ビューからのSUM(std_cost)
fromは、に集約されるだけなので、ClaimSums
すべてのpat_id
+の組み合わせで同じになることに注意してください。結合基準の一部であるはずのがテーブルにあるかもしれないと思いますが、よくわかりません。その場合、これは単一のインデックス付きビューに折りたたむことができると思います。drug_class
pat_id
drug_class
claims