SQL Serverでマテリアライズドビューを作成する方法は?


101

DWを設計し、具体化されたビューについて聞いた。実際にビューを作成したいのですが、ベーステーブルが変更されると自動的に更新されます。誰でもクエリの例で説明できますか?

回答:


144

これらはSQL Serverではインデックス付きビューと呼ばれます。詳細については、以下のホワイトペーパーをご覧ください。

基本的に、あなたがする必要があるのは:

  • 通常のビューを作成する
  • そのビューにクラスター化インデックスを作成する

これで完了です。

トリッキーな部分は次のとおりです。ビューはかなりの数の制約と制限を満たさなければなりません-それらはホワイトペーパーで概説されています。これを行うと、それだけです。ビューは自動的に更新され、メンテナンスは必要ありません。

追加のリソース:


お返事をありがとうございます。欲しいものを手に入れました。インデックスについても知りたいです。すべてのテーブル構造の準備ができているときに、SQL Serverでスタースキーマ図を生成する方法はありますか?はいの場合、そのためにファクトテーブルをどのように作成しますか?
ディーパック

3
クラスタ化インデックスをビューに配置する場合の制限は広範囲にわたっています。たとえば、ビューは他のビューを参照したり、外部結合を含めることはできません。したがって、より優れたパフォーマンスを必要とする多くのビューは、このメソッドを使用できません。まだ良い答えです。
ジェフウィルソン

1
関連する質問で述べたように、MSDNブログ記事blogs.msdn.microsoft.com/ssma/2011/06/20/…は、マテリアライズドビューとインデックス付きビューの主な違いのいくつかを強調しています。最も問題のあるIMHOは更新トリガーを指定できません。ベーステーブルが更新されるたびにインデックス付きビューが更新されるため、マテリアライズドビューを使用することによるパフォーマンス上の利点のほとんどが損なわれます。結合、集計、ウィンドウ関数、およびサブクエリの禁止により、データが頻繁に変更されない限り、インデックス付きビューはほとんど無意味になります。
Suncat2000 2018年

43

純粋にエンジニアリングの観点からですが、インデックス付きビューは誰もがパフォーマンスを向上させるために使用できるもののように聞こえますが、実際のシナリオは大きく異なります。インデックス付けできるものとできないものに対する制限が多すぎるため、最も必要な場所でインデックス付きビューを使用することに失敗しました。

ビューに外部結合がある場合、それらは使用できません。また、共通のテーブル式は許可されていません...実際、副選択または派生テーブル(partition by句を使用するなど)に順序付けがある場合も、運が悪いです。

インデックス付きビューを利用するのは非常に単純なシナリオだけですが、私の考えでは、いずれにしても、基になるテーブルに適切なインデックスを作成することで最適化できます。

人々が実際にインデックス付きビューを自分の利益のために使用し、それらなしでは実行できなかったいくつかの実際のシナリオを聞いてわくわくします


実際、インデックス付きビューを使用して(1回だけ)全文検索インデックスを分割しました。FTSインデックスは実際にはパーティション化できませんが、同じテーブルの複数のビューに個別のインデックスを作成できます。しかし、それは最後の手段のようなものでした。
areyesram 2015年

4
(NOEXPAND)インデックス付きビューを使用するクエリにヒントを追加することを忘れないでください。そして、あなたは違いに気づきます。インデックス付きビューを使用することの利点は、「テーブルに適切にインデックスを付ける」ことと、レコードの選択を制限することです。
ajeh

はい、NOEXPANDのことは控えめに言っても過言ではありません。
Simon_Weaver

18

マテリアライズドビューが実際に何であるかについて、もう少し背景が必要になる場合があります。Oracleでは、これらは他の場所で構築しようとしたときにいくつかの要素で構成されるオブジェクトです。

MVIEWは基本的に、別のソースからのデータのスナップショットです。ビューとは異なり、ビューにクエリを実行してもデータは見つかりません。テーブルの形式でローカルに保存されます。MVIEWは、定期的に、またはソースデータが変更されたときに開始するバックグラウンドプロシージャを使用して更新されます。Oracleでは、完全または部分的な更新が可能です。

SQL Serverでは、以下を使用して、定期的に(完全に)更新する基本的なMVIEWを作成します。

まず、ビュー。ビューはどのデータベースでも非常に一般的であるため、これはほとんどの場合簡単です。次に、テーブルです。これは、列とデータのビューと同じでなければなりません。これは、ビューデータのスナップショットを格納します。次に、テーブルを切り捨て、ビューの現在のデータに基づいてテーブルを再読み込みするプロシージャ。最後に、プロシージャを開始するジョブを開始します。

それ以外はすべて実験です。


5
SQL Serverに関するコメントは正しくありません。マテリアライズドビューは、OracleとSQL Serverではまったく異なります。SQL Serverでは、一意のクラスター化インデックスを含むビュー(別名「マテリアライズドビュー」)はユーザーによって更新されず、更新することも、ユーザーが作成した別のテーブルに保存されることもありません。更新中のエンジンで、同期が取れることはありません。データのスナップショットを保存するジョブは必要ありません。
ErikE 2014年

10
OPが要求したものは、インデックス付きビューによって簡単に提供されます。これは、SQL ServerがOracleマテリアライズドビューにネイティブに提供する最も近いものです。ただし、Oracle MVIEWの動作を正確に再現する必要がある場合は、Jasonが適切です。Jasonのアプローチは、Oracle MVIEWが実行できる同じシナリオでも役立ちます。たとえば、ビューの最新状態よりもデータベースの負荷を重視するレポートテーブルの時間外の更新を実行します(たとえば、昨日の数値のみをレポートします...)

4

インデックス付きビューがオプションではなく、クイックアップデートが必要ない場合は、ハックキャッシュテーブルを作成できます。

select * into cachetablename from myviewname
alter table cachetablename add primary key (columns)
-- OR alter table cachetablename add rid bigint identity primary key
create index...

次に、sp_rename view / table、またはそれを参照するクエリやその他のビューを変更して、キャッシュテーブルを指すようにします。

毎日/毎晩/毎週/更新しないようにスケジュールする

begin transaction
truncate table cachetablename
insert into cachetablename select * from viewname
commit transaction

注意:これは、txログでもスペースを消費します。計算が遅い小さなデータセットに最適です。「簡単だが大きい」列を最初に外側のビューに表示しないようにリファクタリングするかもしれません。


1

MS T-SQL Serverの場合、 "include"ステートメントを使用してインデックスを作成することを検討することをお勧めします。一意性は必須ではなく、クラスター化インデックスに関連付けられているデータの物理的な並べ替えも必要ありません。「Index ... Include()」は、システムによって自動的に維持される個別の物理データストレージを作成します。概念的には、Oracleマテリアライズドビューに非常に似ています。

https://msdn.microsoft.com/en-us/library/ms190806.aspx

https://technet.microsoft.com/en-us/library/ms189607(v=sql.105).aspx

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.