SQLのVIEW(ビュー)は、データベースの中に“仮想テーブル”を作る仕組みです。
名前は知っていても、
-
VIEWは物理的にデータを持つのか?
-
SELECTすると実際にはどう評価されるのか?
-
VIEWをネストしたらパフォーマンスはどうなる?
といった点まで正しく理解されているケースは意外と少ないです。
この記事では、VIEWの“実体”と、クエリ実行時の評価タイミング、パフォーマンスへの影響を分かりやすく解説します。
1. VIEW(ビュー)とは? – 定義文を保存する“仮想テーブル”
VIEWはテーブルのように見えますが、実際にはデータを持っていません。
DBに保存されるのは、以下のような「SQL定義(SELECT文)」だけです。
このv_salesはあたかもテーブルのように扱えますが、中身は 上記SELECT文の“参照” でしかありません。
2. VIEWはいつ“評価”されるのか? – クエリ実行時に展開される
VIEWの最大の誤解ポイントはここです。
ビューは“保存されたSELECT文”なので、クエリ実行のたびに展開されます。
以下のクエリを実行すると、
実際には DB 内部で次のように変換されます。
つまり、
-
VIEWが実体化して保存されるわけではない
-
実行時、その都度“SELECT文の中にインライン展開”される
-
テーブルアクセスもフィルタもすべて本テーブルに作用する
というのがVIEWの基本動作です。
3. DBはVIEWを最適化してくれる – クエリオプティマイザの働き
多くのRDBMS(Oracle / PostgreSQL / MySQL / SQL Server)は、VIEW展開後のSQLを 単一のクエリとして最適化 します。
例えば、
VIEW内にWHERE status='OK'という条件、外側に日付条件があった場合でも、
オプティマイザが結合・条件式をまとめて最適な実行計画に変換する
というのが一般的です。
そのため、VIEWを使ってもパフォーマンスが極端に悪化するわけではありません。
(※もちろん複雑なVIEWの“ネスト”は別の話なので後述)
4. VIEWをネストするとどうなる? – 複雑化 → 最適化が困難化
例えば次のようにVIEWを三重にしてしまうと、
内部ではこんな巨大なSQLに展開されます。
オプティマイザは強力ですが、以下のような場合は最適化が限界に達します。
-
JOINが増えすぎる
-
CASE式やサブクエリが多すぎる
-
DISTINCT・GROUP BYが重複している
-
“VIEWの中でさらにVIEWをJOIN” している
その結果、
-
不要な全表スキャン
-
重複GROUP BYで大量のソート
-
複雑化で実行計画が肥大化
というパフォーマンス低下が起きます。
5. VIEWのメリット
✔ コードの再利用性
複雑なSELECTを1つにまとめて使い回せる。
✔ 可読性の向上
アプリ側のSQLがスッキリする。
✔ 権限管理に使える
特定の列だけ公開するVIEWを作り、ユーザにはVIEWだけ権限付与できる。
6. 気をつけるべきポイント(よくある落とし穴)
❌ VIEWが高速化してくれると思い込む
→ VIEWは基本的には“ただのSQLの保存”。高速化しない。
❌ VIEWを多段に重ねて巨大SQLになっている
→ 実行計画が複雑化しパフォーマンス劣化。
❌ UNION・DISTINCT入りVIEWの多用
→ 展開後に何度もソートが発生する。
❌ VIEW経由にするとインデックスが効かないと思い込む
→ 展開後のSQLにインデックスが適用されるので誤解。
7. MATERIALIZED VIEWとの違い(超重要)
| 種類 | データ保持 | 更新タイミング | 用途 |
|---|---|---|---|
| VIEW (通常VIEW) | 持たない(常に仮想) | 実行時に展開 | 再利用・権限管理・コード整理 |
| MATERIALIZED VIEW | データを保持(物理表) | リフレッシュ時 | 高速化(集計 / 重いJOIN結果のキャッシュ) |
高速化したい時は VIEWではなく MATERIALIZED VIEW を使うのが正解です。
8. VIEWをどう使うべきか?(ベストプラクティス)
✔ 単純ビューを使う
1〜2テーブルのJOIN、軽いWHERE程度に留める。
✔ 複雑なロジックをVIEWに押し込まない
アプリ側に処理を書くか、ストアドやマテリアライズドビューで対応。
✔ 多段VIEWは避ける
どうしても必要な場合は“1段階に統合して新VIEWを作る”。
✔ パフォーマンス課題が出たら、展開SQLを確認する
実行計画を見ると改善点がすぐわかる。
まとめ:VIEWは“実体のないSELECT文”であり、実行時に展開される
ポイントを整理すると:
-
VIEWはデータを持たない(仮想テーブル)
-
DBはVIEW定義を毎回展開し、1つのSQLとして最適化する
-
単純なVIEWは便利だが、多段ビューはパフォーマンス悪化の原因
-
高速化目的なら MATERIALIZED VIEW を使うべき
VIEWは便利な反面、仕組みを誤解すると性能劣化の原因にもなります。
“何がどう評価されているのか”を理解した上で、適切に設計しましょう。
