8

そのため、SQL Server 2008では定義にCTEを使用してビューにインデックスを付けることはできませんがalter、クエリwith schemabindingでビュー定義に追加することはできます。これには正当な理由がありますか?私が知らない何らかの理由でそれは理にかなっていますか?WITH SCHEMABINDINGビューのインデックスを作成できるようにすることが主な目的であるという印象を受けました

より多くのクエリアクションで新しく改善されました

;with x
as
(
    select   rx.pat_id
            ,rx.drug_class
            ,count(*) as counts
            from rx
            group by rx.pat_id,rx.drug_class

)
select   x.pat_id
        ,x.drug_class
        ,x.counts
        ,SUM(c.std_cost) as [Healthcare Costs]
    from x
    inner join claims as c
    on claims.pat_id=x.pat_id
    group by x.pat_id,x.drug_class,x.counts

そして、インデックスを作成するためのコード

create unique clustered index [TestIndexName] on [dbo].[MyView]
( pat_id asc, drug_class asc, counts asc)
4

1 に答える 1

16
  1. CTEを使用してビューにインデックスを付けることはできません。ビューが持つことができSCHEMABINDINGますが。このように考えてください。ビューにインデックスを付けるには、2つの条件(および他の多くの条件)を満たしている必要があります。(a)ビューが作成されていることWITH SCHEMABINDING、および(b)CTEが含まれていないことです。ビューをスキーマバインドするために、CTEが含まれていないという条件を満たす必要はありません

  2. ビューにCTEがあり、インデックスを作成することでメリットが得られるシナリオがあるとは思いません。これはあなたの実際の質問の周辺ですが、私の本能は、魔法のように高速化するためにこのビューにインデックスを付けようとしているということです。インデックス付きビューは、必ずしもベーステーブルに対するクエリよりも高速になるとは限りません。理由による制限があり、それらが意味をなす特定のユースケースのみがあります。すべてのビューを魔法の「高速化」ボタンとして盲目的にインデックス付けしないように注意してください。また、インデックス付きビューにはメンテナンスが必要であることを忘れないでください。そのため、ベーステーブルに影響を与えるワークロード内のすべてのDML操作のコストが増加します。

  3. スキーマバインディングは、ビューのインデックス作成だけを目的としたものではありません。また、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_classpat_iddrug_classclaims

于 2013-03-26T20:29:51.500 に答える