【まてりあらいずどびゅー】

マテリアライズドビュー とは?

💡 ビューの結果を「実体として保存」して高速に読み出す仕組み
📌 このページのポイント
通常のビュー マテリアライズドビュー 元テーブル ビュー定義 SELECT ... GROUP BY ... 仮想テーブル クエリ1回目 クエリ2回目 毎回再実行 (遅い) 元テーブル 保存済み結果 実体テーブル 定期更新 REFRESH クエリ1回目 クエリ2回目 保存結果を読取 (高速)
マテリアライズドビューの仕組み
ひよこ ひよこ

普通のビューとどう違うの?

ペンギン先生 ペンギン先生

普通のビューは「保存されたSELECT文」で、参照するたびにSQLを実行し直す。マテリアライズドビューは結果データをテーブルのようにディスクに保存するから、参照時は保存済みのデータを返すだけで速い。ただしデータが古くなる(元テーブルが更新されても自動では反映されない)のがトレードオフ。

ひよこ ひよこ

どういう場面で使うの?

ペンギン先生 ペンギン先生

「日別の売上集計」「月次レポート」のように計算が重くて、リアルタイム性がそこまで求められないケース。毎回数億行を集計するより、結果を保存しておいて定期的にREFRESHするほうがずっと効率的。ダッシュボードの裏側でよく使われるよ。

ひよこ ひよこ

REFRESHってどうやるの?

ペンギン先生 ペンギン先生

PostgreSQLなら「REFRESH MATERIALIZED VIEW view_name」で再計算できる。CONCURRENTLY オプションを付ければ、リフレッシュ中もビューを読み取れる(ただしUNIQUEインデックスが必要)。リフレッシュはcronジョブやスケジューラで定期実行するのが一般的。

ひよこ ひよこ

MySQLにはマテリアライズドビューってないの?

ペンギン先生 ペンギン先生

MySQL には組み込みのマテリアライズドビュー機能がない。代わりにテーブルトリガー、あるいはイベントスケジューラを組み合わせて自前で似た仕組みを作ることになる。実はマテリアライズドビューの運用で一番悩ましいのは「いつREFRESHするか」の設計。頻繁すぎるとDB負荷が高いし、間隔が長すぎるとデータが古い。さらにCONCURRENTLYなしのREFRESHはビューに排他ロックがかかって参照もブロックされるから、大量データのREFRESHが何分もかかると参照側がタイムアウトする。本番環境での運用はかなり気を使う部分なんだ。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
マテリアライズドビューって出てきたら「ビューの結果を実体として保存しておいて、重い集計を高速化する仕組み」と思えばだいたいOK!
📖 おまけ:英語の意味
「Materialized View」 = 実体化された(Materialized)ビュー(View)
💬 Materializeは「実体化する」。通常のビューが仮想テーブルなのに対し、実体を持つビューという意味
← 用語集にもどる