マテリアライズドビュー(Materialized View)
1. 概要
A. 定義
マテリアライズドビュー(Materialized View)とは、ビューを定義する問い合わせ(SELECT)の結果集合を実際の物理テーブルとしてディスクに保存(precompute・persist)しておき、元(基礎)テーブルが変化するとリフレッシュ(refresh)で同期させる事前計算されたビューである。問い合わせが参照されるたびに毎回再計算する通常ビュー(仮想ビュー)とは異なり、マテリアライズドビューは「計算を先に済ませ、空間を割いて時間を買う」典型的な空間-時間トレードオフ(space-time trade-off)の構造物である。
B. 登場背景および必要性
関係データベースにおいてビュー(View)は、複雑な結合・集計・フィルタを一つの名前で抽象化し、再利用性とセキュリティを高める手段として広く用いられてきた。しかし従来のビューは定義だけが保存され、データは保存されない仮想オブジェクトであるため、ビューを問い合わせるたびに元テーブルを再び結合・集計する。数億件のファクトテーブルに対する多重結合・GROUP BY集計をダッシュボードが分単位で繰り返し呼び出すと、同一の重い計算が際限なく繰り返され、CPU・I/Oが飽和する。
この問題は特にOLAP(分析)・データウェアハウス環境で顕著である。分析問い合わせは「前四半期の地域別売上合計」のように読み取り中心であり、元の変更周期(日・時間単位)よりも照会頻度(秒・分単位)がはるかに高い。すなわち同じ結果を毎回再計算することは明白な無駄である。マテリアライズドビューはこの結果を一度計算して物理的に保存しておき、以後の照会は保存された結果を単純にスキャンすることで代替する。元が変わると全体あるいは変化した部分のみ(増分)を反映するため、「常に最新」と「常に高速」の間で要求水準に合った遅延(staleness)許容値を選べるようになる。
この必要性は、「ビュー」という抽象化の二つの本性 — 論理的再利用と物理的性能 — が従来ビューでは分離していたことに由来する。従来ビューは論理的再利用(抽象化・セキュリティ)は提供するが、物理的性能は毎回の再計算に委ねる。マテリアライズドビューはここに物理的実体(保存された結果)を加えて二つの本性を一つのオブジェクトに統合したものであり、「ビューの利便性は保ちつつ繰り返し計算は除く」折衷点である。まさにこの点が、要約テーブルを手作業で作りトリガーで管理していた過去の慣行よりも優位に立たせた理由である。
さらにマテリアライズドビューは単なるキャッシュを超え、問い合わせ最適化器と結合する点でアプリケーションキャッシュと区別される。Oracle・PostgreSQL・SQL Server(インデックス付きビュー)・Snowflake・BigQueryなど主要システムは、利用者が元テーブルを直接問い合わせても、最適化器がマテリアライズドビューがその問い合わせを代わりに満たせるかを判断し、自動的にビューを読むよう書き換える(Query Rewrite)。おかげでアプリケーションコードを変えずとも性能の利得を透過的に享受でき、大規模レポーティング・BIアーキテクチャの中核的な加速手段として定着した。
C. 特徴
マテリアライズドビューの性質は、「保存によって得る利得」と「保存から生じる費用」が表裏一体をなす点で理解しなければならない。結果を物理的に保存するため照会は速くなるが、保存された結果は元と即座に一致せず、リフレッシュという別途の作業を通じてのみ最新へ収束する。したがってマテリアライズドビューを導入するということは、「どの程度の遅延を、どの程度のリフレッシュ費用で甘受するか」を設計することに等しい。以下の特徴はすべてこの本質から派生する。
- 結果の物理的保存: 問い合わせ結果が実テーブルとして保存され、インデックス・パーティショニングを追加適用できる。
- 遅延同期(eventually fresh): 元との整合はリフレッシュ時点まで遅延し、リフレッシュ戦略で新鮮度を調節する。
- 透過的な加速(query rewrite): 最適化器が元の問い合わせをマテリアライズドビューへ自動置換できる。
- 増分維持が可能(incremental): 変化分のみを反映するfast refreshでリフレッシュ費用を最小化する。
- 冗長保存の費用: 結果を元と別に保持するためストレージ・リフレッシュ負担が増え、一貫性管理の責任が加わる。
- 用途別に分離可能: 同一の元から新鮮度・粒度の異なる複数のビューを置き、レポート・ダッシュボード・探索分析など用途に合わせて各々異なるリフレッシュ方針を適用できる。
2. マテリアライズドビューの全体構造
flowchart TB
subgraph SRC["基礎(元)テーブル"]
B1["Sales (ファクト)"]
B2["Region (ディメンション)"]
end
MVLOG["マテビューログ(MV Log)<br/>変化分(delta)を記録"]
subgraph MV["マテリアライズドビュー (物理保存)"]
MVT[("保存された結果集合<br/>地域別売上合計")]
IDX["補助インデックス/パーティション"]
end
OPT["問い合わせ最適化器<br/>(Query Rewrite)"]
USR["利用者の問い合わせ(SELECT)"]
B1 -->|"変更(INSERT/UPDATE/DELETE)"| MVLOG
B2 --> MVLOG
MVLOG -->|"refresh(増分/完全)"| MVT
MVT --- IDX
USR --> OPT
OPT -->|"元の代わりにMVをスキャン"| MVT
OPT -. "書き換え不可時" .-> B1
マテリアライズドビューは四つの論理要素として理解すれば明確である。第一に、基礎テーブル(base table)はマテリアライズドビュー定義の問い合わせが参照する元であり、ここで発生する変更がビューの新鮮度を下げる源泉である。第二に、保存された結果集合はビュー問い合わせを実行して得た行を収めた実セグメントで、通常テーブルのようにインデックス・パーティション・圧縮を適用でき、照会をさらに加速する。第三に、マテビューログ(Materialized View Log)は増分リフレッシュのために基礎テーブルの変化分(delta)を別途記録する補助構造で、これがあってこそ全体再計算なしに「変わった行のみ」を反映できる。第四に、最適化器の問い合わせ書き換えは利用者が元を問い合わせてもビューへ迂回させ、透過的な加速を提供する。
この構造の核心は書き込み経路と読み取り経路の分離である。元の変更はログに積まれ(書き込み)、照会は事前計算された結果を読む(読み取り)。二つの経路が分離するため、照会性能が元テーブルの大きさ・結合の複雑さから隔離(decoupling)される。これは読み取りと書き込みのモデルを分離するCQRS(コマンド・クエリ責務分離)の思想とも通じるが、マテリアライズドビューはDBMS内部で「照会専用の読み取りモデル」を宣言的に構成する手段とみなせる。ただしCQRSがアプリケーション層で二つのモデルを明示的に運用するのとは異なり、マテリアライズドビューはリフレッシュ・整合をDBMSが代わりに担う点で運用負担が低い。
以下の表は、通常ビュー・マテリアライズドビュー・アプリケーションキャッシュの違いがどこから生じるかを示す。通常ビューは保存がなく常に最新だが毎回再計算して遅く、マテリアライズドビューは保存によって速いがリフレッシュ遅延が生じ、アプリケーションキャッシュはDBMSの外にあるため最適化器が知らず自動書き換えが不可能である。
| 区分 | 通常(仮想)ビュー | マテリアライズドビュー | アプリケーションキャッシュ |
|---|---|---|---|
| データ保存 | なし(定義のみ) | 物理的に保存 | 外部保存(Redis等) |
| 新鮮度 | 常に最新 | リフレッシュ時点まで遅延 | 失効・無効化に依存 |
| 照会性能 | 毎回再計算(遅い) | 事前計算(速い) | 速い |
| 最適化器の認識 | 該当なし | 自動書き換え可能 | 不可(透過性なし) |
| 一貫性の責任 | DBMS | DBMS(リフレッシュ方針) | アプリケーション |
3. リフレッシュ(Refresh)のメカニズム
sequenceDiagram
participant App as アプリケーション
participant Base as 基礎テーブル
participant Log as MVログ(delta)
participant MV as マテリアライズドビュー
App->>Base: INSERT/UPDATE/DELETE
Base->>Log: 変化分(行key・演算)を積載
alt ON COMMIT (即時増分)
Base-->>MV: コミット時にdeltaを反映(fast refresh)
else ON DEMAND (遅延)
App->>MV: REFRESH呼び出し
MV->>Log: deltaを読み増分適用
Note over MV,Log: deltaなし又は集計複雑なら完全再計算
end
App->>MV: 分析問い合わせ(SELECT)
MV-->>App: 事前計算結果を返す
マテリアライズドビューの価値と費用を分ける決定的な要素はリフレッシュ戦略である。大きく二つの軸 — 何を再計算するか(完全 vs 増分)といつ行うか(即時 vs 遅延) — に分かれる。
ここで「何を」と「いつ」は互いに直交する軸なので組み合わせが可能である。完全リフレッシュを夜間バッチ(ON DEMAND)で回すことも、増分リフレッシュをコミット時点(ON COMMIT)に付けることもできる。設計者は二つの軸を独立に選び、「完全+夜間」「増分+周期」「増分+リアルタイム」のように業務要求に合った地点を選ぶ。以下で各軸の選択肢を順に見ていく。
A. 完全リフレッシュ(Complete Refresh)はビュー定義の問い合わせを最初から再実行し、結果を丸ごと置き換える。実装が単純でどの問い合わせにも適用できるが、元が大きいほど費用が線形に増える。数億件のファクトに対する多重結合集計を毎時完全リフレッシュすれば、それ自体がもう一つの重いバッチになってしまう。したがって完全リフレッシュは元の規模が小さいか、変更が全面的か、増分が不可能な複雑集計に限定するのが望ましい。
B. 増分(高速)リフレッシュ(Fast/Incremental Refresh)はマテビューログに積まれた変化分(delta)のみを反映する。例えば売上1,000万件のうち直近1時間に1万件が追加されたなら、その1万件が影響を与えた集計グループのみを更新する。費用が「元の大きさ」ではなく「変化量」に比例するため、変化率が低い大規模テーブルで劇的な効果を出す。ただし増分が成立するにはビュー定義が増分維持可能な形でなければならない。一般にSUM・COUNTのような加算(additive)集計は増分が容易だが、AVGはSUM/COUNTへ分解せねばならず、MAX・MINは削除が混じると再計算が必要になりうるほか、DISTINCT・入れ子サブクエリ・外部結合の一部は増分が制限される。この制約を知らずに設計すると、「fast refreshを掛けたのに実際は完全リフレッシュに落ちる」罠にはまる。
C. リフレッシュ時点(同期 vs 非同期)は新鮮度と書き込み負担の均衡点を定める。ON COMMIT(同期)は元のトランザクションがコミットする際にビューを共に更新し、ほぼリアルタイムの整合を保証するが、書き込みトランザクションにリフレッシュ費用を載せてOLTPの書き込み遅延を増す。ON DEMAND(非同期)はスケジューラや手動呼び出しで周期的(例:5分・1時間)にリフレッシュして書き込み経路を軽く保つが、その分データが最大周期分だけ過去(stale)になる。実務では「ダッシュボードは5分遅延許容」のように業務が許容する遅延を先に定義し、それに合わせてON DEMAND周期を決める方式が一般的である。
D. リフレッシュ中の可用性(同時実行)も運用で重要である。従来の完全リフレッシュは、ビューを空にして詰め直す間照会が遮断されたり空の結果を見る問題があった。これを解決するためPostgreSQLはREFRESH MATERIALIZED VIEW CONCURRENTLYで既存ビューを読める状態に置いたまま新結果を作ってから置き換える無停止リフレッシュを支援し(ただし一意インデックスが必要)、Oracleはatomic_refreshオプションでトランザクション原子性を調節する。24×7サービスではリフレッシュ自体が照会SLAを破らないよう同時実行モデルを必ず確認せねばならず、大容量ビューはパーティション交換(partition exchange)で影響範囲を一パーティションに限る技法が広く使われる。
4. 問い合わせ書き換え(Query Rewrite)と活用
マテリアライズドビューが単なる要約テーブル(summary table)と決定的に異なる点が問い合わせ書き換えである。利用者が元のファクトテーブルを直接集計するSQLを投げても、最適化器は意味的に同値なマテリアライズドビューが存在するかを検査し、存在すれば元の代わりにビューを読むよう実行計画を変える。アプリケーションはビューの存在を知らなくてよく、DBAは性能が必要な地点にビューを追加・削除するだけでコード変更なしに性能を調律できる。書き換えが成立するにはビューが要求問い合わせを「包含」せねばならず、例えば日別集計ビューがあれば月別問い合わせはそのビューを再びGROUP BYする形でロールアップ(rollup)書き換えが可能である。逆により細かいレベルを要求すれば書き換えが不可能で元へ戻る。
書き換えのもう一つの前提は集計可能性(aggregate navigability)である。より粗い単位のビューでより細かい問い合わせを満たすことはできないので、ビューの粒度(granularity)は想定される問い合わせパターンの最も細かい共通分母に合わせるのがよい。日別ビュー一つで日・週・月・四半期の問い合わせをロールアップで賄えるが、時間帯別の問い合わせが必要になれば再び元へ落ちるためである。したがってどのビューを何個、どの粒度で置くかは問い合わせログ分析に基づく設計判断であるべきで、やみくもに多くのビューを置けばリフレッシュ・保存費用だけが増える。
ただし問い合わせ書き換えには最適化器がビューと元の関係を信頼できねばならないという前提が伴う。OracleではQUERY_REWRITE_INTEGRITY水準(ENFORCED・TRUSTED・STALE_TOLERATED)に応じて、外部キー・制約が検証された場合のみ書き換えるか、宣言された制約(RELY)ややや古いビューまで許すかを調節する。新鮮度が落ちたビューへ書き換えると速いが誤った答えを返しうるので、書き換え整合性水準とビューのリフレッシュ周期を共に設計することが重要である。この点がマテリアライズドビューを「性能オブジェクト」であると同時に「整合性オブジェクト」として扱うべき理由である。
活用の観点でマテリアライズドビューは三つの領域で際立つ。第一に、OLAP集計の加速である。データウェアハウスのスタースキーマでよく使う地域・期間・商品別要約をマテリアライズドビューにしておけば、ダッシュボードの応答が数十秒から数百ミリ秒へ縮む事例が多い。第二に、遠隔・分散データ複製である。元が別のDBにある場合、マテリアライズドビューで結果をローカルに複製・周期リフレッシュすれば、ネットワーク往復と遠隔負荷を減らす読み取りレプリカの役割をする。第三に、事前結合(pre-join)である。重い多対多結合を先に解いて保存し、繰り返される結合費用を除く。
5. 類型比較および適用事例
リフレッシュ戦略の選択は業務特性により異なる。以下の表は代表的な組み合わせと適する状況を整理したもので、各項目の根拠は「変化量 対 照会量」と「許容遅延」という二つの軸に還元される。
| 戦略の組み合わせ | 新鮮度 | リフレッシュ費用 | 適する状況 |
|---|---|---|---|
| 完全 + ON DEMAND(夜間バッチ) | 低(日単位) | 高(全体) | 日単位レポート、増分不可の複雑集計 |
| 増分(fast) + ON DEMAND(5~15分) | 中 | 低(delta) | 準リアルタイムBIダッシュボード |
| 増分(fast) + ON COMMIT | 高(リアルタイム) | 書き込みに加算 | 最新性必須・書き込み量少の小型集計 |
この比較で繰り返される判断基準は、結局三つの問いに要約される。(1)データがどれだけ頻繁に変わるか(変化率)、(2)どれだけ古いデータまで許容されるか(新鮮度SLA)、(3)同じ結果がどれだけ頻繁に照会されるか(再利用率)。変化率が低く再利用率が高く新鮮度要求が緩いほどマテリアライズドビューの利得が大きく、逆の状況では通常ビューやインデックスのほうが合理的である。この三軸で候補の問い合わせを点数化してビュー導入可否を決めれば過剰設計を避けられる。
具体的な事例として、ある通信会社の料金分析ダッシュボードが夜間に全ファクト2億件を完全リフレッシュするのにバッチが3時間超かかったとしよう。これを日付パーティション単位の増分リフレッシュ + 15分周期のON DEMANDに変えれば、一日の新規発生分(約70万件、全体の0.35%)のみを反映するためリフレッシュが数分以内に短縮され、ダッシュボードの新鮮度も一日から15分へ向上する。核心はリフレッシュ費用を2億件全体ではなく変化した0.35%に比例するよう変えた点にあり、この「変化率が低いほど増分の利得が大きい」という原理が戦略選択の一般法則として働く。
金融業界の事例では、規制レポートのように整合が絶対的な指標はON COMMIT増分でリアルタイム一致を保証し、マーケティング探索用集計のように遅延が許容される指標は1時間のON DEMANDで資源を節約する混合構成が多い。同じデータでも「何に使うか」により新鮮度要求が異なるため、ビューを用途別に分けて互いに異なるリフレッシュ方針を適用する設計が現実的である。クラウドDWでもSnowflakeの自動維持マテリアライズドビュー、BigQueryの増分MV、PostgreSQLのREFRESH MATERIALIZED VIEW CONCURRENTLY(リフレッシュ中の照会無停止)など実装別に特性が異なるため、プラットフォームの増分支援範囲と同時実行モデルを先に確認することが設計の出発点である。
6. 深化 — 増分ビュー維持とストリーミング分析への拡張
近年マテリアライズドビュー技術は増分ビュー維持(IVM, Incremental View Maintenance)理論を基盤に、より広い問い合わせを増分化する方向へ進化している。従来のfast refreshが単純集計・結合に限られていたのとは異なり、IVMはビュー定義を代数的に微分(differentiation)し、任意の挿入・削除・更新が結果に与える変化量(ΔResult = f(ΔInput))を計算する。PostgreSQLのpg_ivm拡張、Materialize・RisingWaveのようなストリーミングデータベースがこの手法を商用化し、元が変わると即座にミリ秒単位でビューを更新するリアルタイムマテリアライズドビュー(streaming materialized view)を提供する。これは「バッチで周期更新する要約テーブル」という従来の概念を、「変化を流しながら結果を常に最新に保つ連続問い合わせ(continuous query)」へ再定義したものである。
IVMが重要なのは「増分可能な問い合わせ」の境界を広げるためである。従来のfast refreshが加算集計・単純結合など限られたパターンのみを扱ったのに対し、IVMは関係代数の演算子ごとに変化伝播規則を定義し、結合・集計・フィルタが結合した複合問い合わせも増分で維持する。例えば結合ビューで一方のテーブルに行が追加されると、反対側との結合結果の増分のみを計算してビューに加える。この手法は変化量が小さい限り元の規模と無関係に一定のリフレッシュ費用を達成するため、数十億件のテーブル上でもリアルタイムに近い集計を可能にする。ただし削除・更新が混じると負のdelta(retraction)処理が必要で実装が複雑になり、状態(state)を維持するためのメモリ・ストレージ費用が加わる点はトレードオフとして残る。
もう一つの流れはデータウェアハウス・レイクハウスでの自動化である。dbtのincremental model、DatabricksのMaterialized View・Delta Live Tables、SnowflakeのDynamic Tableは、利用者が最終結果の問い合わせと目標新鮮度(target lag)だけを宣言すれば、増分可否・リフレッシュ周期・依存順序をプラットフォームが自動で管理する。すなわち「どう更新するか(how)」を人が組んでいた時代から、「何を・どれだけ新鮮に(what・how fresh)」だけを宣言する宣言型(declarative)データ変換へ重心が移りつつある。この変化はCDC(変更データキャプチャ)・メッセージキューと結合して、リアルタイム分析パイプラインの標準構成要素へマテリアライズドビューを押し上げており、技術士の観点ではバッチETL中心のアーキテクチャがストリーミング・宣言型維持へ収束する巨視的趨勢の一断面として読むべきである。
一方、こうした自動化が万能ではない点も併せて押さえるべきである。宣言型プラットフォームは「目標新鮮度」を約束するが、その約束を守るため内部ではより頻繁な増分計算と状態維持を行うので、計算費用が新鮮度とほぼ線形に増える。クラウド課金環境では「リアルタイムに見えるダッシュボード」が静かに大きな費用を生みうるため、FinOpsの観点の新鮮度-費用モニタリングが必須である。結局、技術は「どう」を自動化しただけで、「どれだけ新鮮であるべきか」という業務的判断は依然として設計者の役割として残る。
7. 考慮事項および示唆点
マテリアライズドビューは強力だが「ただの加速」ではなく、次のような技術士の観点のトレードオフを共に設計せねばならない。特に性能の利得だけに注目して導入し、リフレッシュ費用・一貫性管理・ガバナンスの後始末に悩まされる場合が多いため、導入前に費用の側面を先に定量化する態度が必要である。
- 新鮮度 vs 費用の明示的合意: まず業務が許容する遅延(SLA)を定義せねばならない。リアルタイムが必ず要る指標とそうでない指標を区分してON COMMIT・ON DEMANDを混合し、やみくもに短いリフレッシュ周期を取って資源を消費する過剰設計を避ける。「すべてリアルタイム」は費用・書き込み遅延の面で大抵不合理である。
- 増分可能性の事前検証: ビュー定義がfast refresh要件(加算集計・単純結合・必要なMVログ)を満たすかを設計段階で検証せねばならない。増分が成立しないと完全リフレッシュへ静かに退化し性能目標が崩れる。
AVG→SUM/COUNT分解、MAX/MINの削除処理、DISTINCT制約などを先に反映する。 - 保存・インデックスのオーバーヘッドと運用の複雑さ: マテリアライズドビューは結果を冗長に保存するためストレージが増え、ビューに掛けたインデックスはリフレッシュのたびに共に維持され書き込み負担を加える。ビューの数が増えると、どの問い合わせがどのビューへ書き換えられるかの追跡・ガバナンスが難しくなるので、ビューカタログ・命名規則・利用率モニタリングを共に運用する。
- 一貫性の境界と代替手段との比較: マテリアライズドビューは「最終的一貫性」を前提とするので、元と即座に一致せねばならないトランザクション処理には不適である。この場合、通常ビュー・カバリングインデックス・カラムストア・結果キャッシュなど代替と比較して選ばねばならない。特に単一問い合わせの加速が目的ならインデックスが、繰り返し集計の加速が目的ならマテリアライズドビューが、全面的な分析加速が目的ならOLAPキューブ・カラム型保存のほうが適しうる。
- モニタリングとライフサイクル管理: ビュー別のリフレッシュ所要時間・失敗率・最終リフレッシュ時刻・書き換え命中率を指標化して持続観察せねばならない。使われないビューはリフレッシュ費用だけを消費する負債なので、利用率が低いビューは果断に廃棄するライフサイクル管理が必要である。
- 展望と連携技術: ストリーミングIVM・宣言型DW(Dynamic Table・DLT)の成熟により、マテリアライズドビューはバッチ要約を超えリアルタイム分析の一級構成要素へ拡張されている。CDC・メッセージキュー・レイクハウスとの連携設計を併せて考慮すれば、バッチ・ストリーミングを貫く一貫した分析アーキテクチャを構築できる。
参考資料
- Oracle, "Database Data Warehousing Guide — Basic Materialized Views / Refresh", https://docs.oracle.com/en/database/oracle/oracle-database/19/dwhsg/basic-materialized-views.html
- PostgreSQL Documentation, "CREATE MATERIALIZED VIEW / REFRESH MATERIALIZED VIEW", https://www.postgresql.org/docs/current/sql-creatematerializedview.html
- Snowflake Documentation, "Working with Materialized Views", https://docs.snowflake.com/en/user-guide/views-materialized
- Google Cloud, "Introduction to materialized views (BigQuery)", https://cloud.google.com/bigquery/docs/materialized-views-intro
一言まとめ: マテリアライズドビューはビュー問い合わせの結果を物理的に保存し完全・増分リフレッシュで同期させる空間-時間トレードオフの構造で、問い合わせ書き換えによる透過的なOLAP加速からストリーミングIVM基盤のリアルタイム分析まで拡張され、「新鮮度 vs 費用」を業務SLAに合わせて設計することが核心である。