マテリアライズドビュー
Materialized View
重い集計クエリの結果を実体として保存し、読み取りを速くする代わりに鮮度を管理する仕組み。
概要
マテリアライズドビュー(実体化ビュー)は、SQL クエリの結果をその場で計算するのではなく、あらかじめ計算してテーブルのような「実体」としてディスクに保存しておく仕組みです。「月別売上サマリ」「ユーザーごとの投稿数ランキング」のような、複数テーブルの結合と集計を伴う重いクエリの結果を事前に作り置きしておき、参照時にはその作り置きを読むだけにする — いわばデータベース内蔵のキャッシュです。
日常的には管理画面やダッシュボード、レポート機能の高速化で登場します。元データが数億行あっても、集計済みの結果が数千行なら読み取りは一瞬です。その代わり、元データが更新されても作り置きは自動では変わらないため、「いつ・どうやって作り直すか(リフレッシュ)」と「どこまでの古さを許容するか(鮮度)」の管理がこの仕組みの中心的なテーマになります。
なぜ生まれたか
RDBMS には古くから「ビュー」という仕組みがあります。ビューは複雑なクエリに名前を付けたもので、参照するたびに元のクエリがその場で実行されます。定義の再利用や権限の切り分けには便利ですが、性能は1ミリも改善しません。ビューの裏側が「5つのテーブルを結合して全行を集計する」クエリなら、ダッシュボードを開くたびにその全計算が走ります。
データ量が増え、BIやレポーティングのように「同じ重い集計を何度も参照する」利用が広がると、毎回の再計算は明らかな無駄になりました。参照のたびに答えが変わるわけでもない集計を、なぜ毎回ゼロから計算するのか — この無駄を省くため、「クエリの結果そのものを実体として保存し、再計算は明示的なタイミングだけにする」マテリアライズドビューが、Oracle をはじめとする商用データベースで実装され(当初は「スナップショット」と呼ばれました)、その後 PostgreSQL など主要な RDBMS に広がりました。計算のタイミングを「読むとき」から「書くとき・更新するとき」へ移す、という発想の転換です。
詳細
通常のビューとの違い — 計算するタイミングが逆
両者の違いは「クエリがいつ実行されるか」に尽きます。通常のビューは参照のたびに元テーブルへクエリが走るため、常に最新である代わりに毎回重い。マテリアライズドビューはリフレッシュ時にだけクエリが走り、参照は保存済み結果を読むだけなので速い代わりに、前回リフレッシュ以降の変更は反映されません。
実体を持つということは、テーブルと同じようにインデックスを張れるということでもあります。集計結果にさらに検索条件を掛けるダッシュボードでは、マテリアライズドビュー + インデックスの組み合わせが強力に効きます。オプティマイザが元テーブルへのクエリを自動でマテリアライズドビュー参照に書き換えてくれる機能(クエリリライト)を持つデータベースもあり、その場合はアプリ側のクエリを変えずに恩恵を受けられます。効いているかどうかは実行計画で確認できます。
リフレッシュ戦略 — 鮮度と負荷のトレードオフ
リフレッシュの設計が、この仕組みの成否を分けます。もっとも単純なのは全体再計算(PostgreSQL の REFRESH MATERIALIZED VIEW)で、確実ですが元クエリの全コストが毎回かかります。夜間バッチや1時間おきの定期実行と組み合わせるのが典型で、「最大1時間古いデータが見える」ことを仕様として許容する判断とセットになります。なお素朴な全体リフレッシュは実行中に参照をブロックするため、PostgreSQL では CONCURRENTLY オプションで参照を止めずに入れ替えるのが実務の定番です。
より進んだ方式が増分リフレッシュ(incremental refresh / incremental view maintenance)です。元テーブルの変更差分だけを使ってビューを部分更新するもので、Oracle のマテリアライズドビューログを使った fast refresh が代表例です。全体再計算に比べ圧倒的に軽い一方、対応できるクエリの形(結合や集計の種類)に制約があります。さらにこの発想を推し進め、変更ストリームから集計結果を常時更新し続ける仕組みはストリーム処理の領域と地続きで、Materialize のような「常に最新のマテリアライズドビュー」を掲げる専用エンジンも登場しています。
どの方式でも本質は同じトレードオフです。鮮度を上げるほどリフレッシュの頻度・仕組みのコストが上がり、下げるほど「古いデータを見せるリスク」が上がる。これはキャッシュの無効化問題と同型であり、「このデータはどれだけ古くてよいか」を業務要件として明確にすることが設計の出発点になります。
使いどころと落とし穴
マテリアライズドビューが輝くのは、「書き込みより読み取りがずっと多く」「多少古くてもよく」「計算が重い」データです。ダッシュボード、ランキング、月次レポート、全文検索用の非正規化テーブルなどが典型です。読み取り用に最適化した形を書き込みモデルと分けて持つという点で、CQRS の読み取りモデルをデータベース機能だけで実現した最小構成と見ることもできます。逆に、残高や在庫のように常に厳密な最新値が必要なデータには不向きで、そこは元テーブルを直接参照すべきです。
実務の落とし穴としては、リフレッシュのバッチが静かに失敗し、誰も気づかないまま古いデータが表示され続けるパターンが代表的です。リフレッシュの成否と最終更新時刻は監視の対象に含めておくべきです。また、マテリアライズドビューが増殖して依存関係が絡まり、リフレッシュの順序管理が新たな複雑さになることもあります。「重いクエリはとりあえずマテビュー化」ではなく、鮮度要件を確認したうえで、依存の浅い少数のビューに絞って使うのが健全な運用です。
