> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-postgresql-tls-support.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# materialized view とプロジェクションの違い

> ClickHouse における materialized view とプロジェクションのユースケース、パフォーマンス、制限事項の違いを比較する記事です。

> ユーザーからよく寄せられる質問の 1 つに、materialized view と
> プロジェクションのどちらを使うべきか、というものがあります。この記事では、この 2 つの主な違いと、
> 状況に応じてどちらを選ぶべきかを説明します。

<div id="key-differences">
  ## 主な違いの要約
</div>

以下の表は、materialized view とプロジェクションの主な違いを、さまざまな観点から要約したものです。

| Aspect                                                                                     | Materialized views                                                                                                                                                                                                 | Projections                                                                                                                                              |
| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| データの保存場所と配置                                                                                | 結果は**独立した明示的ターゲットテーブル**に保存され、ソーステーブルへの `INSERT` に対する INSERT 時の insert trigger として動作します。                                                                                                                            | プロジェクションは最適化されたデータレイアウトを作成し、**メインテーブルのデータと一緒に物理的に保存**され、ユーザーからは見えません。                                                                                    |
| 更新メカニズム                                                                                    | ソーステーブルへの `INSERT` に対して**同期的に**動作します (インクリメンタルmaterialized view の場合) 。注: リフレッシュ可能なマテリアライズドビューを使って**スケジュール**することもできます。                                                                                              | メインテーブルへの `INSERT` に応じて、バックグラウンドで**非同期**に更新されます。                                                                                                         |
| クエリとの関わり                                                                                   | materialized view を利用するには、**ターゲットテーブルを直接**クエリする必要があります。つまり、クエリを書く際には materialized view の存在を意識しておく必要があります。                                                                                                          | プロジェクションは ClickHouse のクエリオプティマイザによって**自動的に選択**され、透過的に機能します。そのため、利用するためにユーザーがプロジェクションを持つテーブルへのクエリを変更する必要はありません。バージョン 25.6 以降では、複数のプロジェクションでフィルタすることも可能です。 |
| `UPDATE` / `DELETE` の扱い                                                                    | materialized view はソーステーブルを認識せず、ソーステーブル *への* insert trigger としてのみ動作するため、ソーステーブル上の `UPDATE` や `DELETE` 操作には**自動では反応しません**。このため、ソーステーブルとターゲットテーブルの間でデータが古くなる可能性があり、回避策または定期的なフルリフレッシュが必要です。 (リフレッシュ可能なマテリアライズドビュー経由) | デフォルトでは、**`DELETED` 行と互換性がありません** (特に論理削除) 。`lightweight_mutation_projection_mode` (v24.7+) で互換性を有効にできます。                                                |
| `JOIN` のサポート                                                                               | はい。リフレッシュ可能なマテリアライズドビューは複雑な非正規化に使用できます。インクリメンタルmaterialized view は、左端のテーブルへの insert でのみトリガーされます。                                                                                                                   | いいえ。マテリアライズされたデータをフィルタするためのプロジェクション定義内では `JOIN` 操作はサポートされていません。ただし、プロジェクションを持つテーブルを join するクエリ自体は通常どおり動作します。プロジェクションは個々のテーブルアクセスを最適化します。                 |
| 定義内の `WHERE` clause                                                                        | はい。マテリアライズ前にデータをフィルタするために `WHERE` 句を含めることができます。                                                                                                                                                                    | いいえ。マテリアライズされたデータをフィルタするためのプロジェクション定義内では `WHERE` 句はサポートされていません。                                                                                          |
| 連鎖の可否                                                                                      | はい。1 つの materialized view のターゲットテーブルを別の materialized view のソースとして使えるため、多段 pipeline を構築できます。                                                                                                                        | いいえ。プロジェクションは連鎖できません。                                                                                                                                    |
| 適用可能なテーブルエンジン                                                                              | さまざまなソーステーブルエンジンで使用できますが、ターゲットテーブルは通常 `MergeTree` ファミリーです。                                                                                                                                                         | `MergeTree` ファミリーのテーブルエンジンで**のみ利用可能**です。                                                                                                                 |
| 障害時の扱い                                                                                     | データ挿入中に障害が発生すると、ターゲットテーブル内のデータが失われ、不整合が生じる可能性があります。                                                                                                                                                                | 障害はバックグラウンドで**透過的に**処理されます。クエリはマテリアライズ済みパーツと未マテリアライズのパーツをシームレスに混在させて扱えます。                                                                                |
| 運用上のオーバーヘッド                                                                                | 明示的なターゲットテーブルの作成が必要で、多くの場合は手動での backfill も必要です。`UPDATE`/`DELETE` との整合性管理によって複雑さが増します。                                                                                                                              | プロジェクションは自動的に維持され、同期も保たれるため、一般に運用負荷は低くなります。                                                                                                              |
| `FINAL` クエリとの互換性                                                                           | 一般には互換性がありますが、ターゲットテーブルに対して `GROUP BY` が必要になることがよくあります。                                                                                                                                                            | `FINAL` クエリでは**動作しません**。                                                                                                                                 |
| 遅延マテリアライゼーション                                                                              | はい。                                                                                                                                                                                                                | マテリアライゼーション機能を使う場合は、プロジェクションとの互換性の問題に注意してください。`query_plan_optimize_lazy_materialization = false` の設定が必要になる場合があります。                                       |
| 並列レプリカ                                                                                     | はい。                                                                                                                                                                                                                | いいえ。                                                                                                                                                     |
| [`optimize_read_in_order`](/ja/reference/settings/session-settings#optimize_read_in_order) | はい。                                                                                                                                                                                                                | はい。                                                                                                                                                      |
| 論理更新と論理削除                                                                                  | はい。                                                                                                                                                                                                                | いいえ。                                                                                                                                                     |

<div id="choose-between">
  ## materialized view とプロジェクションの比較
</div>

<div id="choosing-materialized-views">
  ### materialized viewを選ぶべき場合
</div>

次のような場合は、materialized viewの利用を検討してください。

* **リアルタイムETLと多段データパイプライン**に対応する場合: 複雑な変換や集計を実行する必要がある、または到着したデータをルーティングする必要があり、viewを連鎖させて複数段階にまたがる処理を行う可能性がある場合。
* **複雑な非正規化**が必要な場合: 複数のソース (テーブル、サブクエリ、または辞書) のデータを、クエリに最適化された単一のテーブルに事前に結合する必要があり、特にリフレッシュ可能なマテリアライズドビューを使用した定期的なフルrefreshを許容できる場合。
* **明示的なスキーマ制御**を行いたい場合: 事前計算された結果を格納するために、独自のスキーマとエンジンを持つ別個のターゲットテーブルが必要であり、データモデリングにより高い柔軟性を求める場合。
* **インジェスト時にfilter**したい場合: データがmaterializedされる\_前に\_ filterする必要があり、ターゲットテーブルに書き込まれるデータ量を削減したい場合。

<div id="avoid-materialized-views">
  ### materialized viewを避けるべきケース
</div>

次のような場合は、materialized viewの使用を避けることを検討してください。

* **ソースデータが頻繁に更新または削除される**: ソーステーブルとターゲットテーブルの整合性を保つための追加の対策がないと、インクリメンタルmaterialized viewが古い状態になり、一貫性が失われる可能性があります。
* **シンプルさと自動最適化を重視する**: 個別のターゲットテーブルを管理したくない場合です。

<div id="choosing-projections">
  ### プロジェクションを選ぶべき場合
</div>

次のような場合は、プロジェクションの使用を検討してください。

* **単一テーブルのクエリを最適化したい**: 主な目的が、別のソート順を用意したり、プライマリキーに含まれないカラムに対するフィルタを最適化したり、単一の基となるテーブルに対する集計を事前計算したりすることで、そのテーブルに対するクエリを高速化することである場合。
* **クエリの透過性**を求める: クエリを変更せずに元のテーブルを対象とし、指定したクエリに対して最適なデータレイアウトを ClickHouse に選択させたい場合。

<div id="avoid-projections">
  ### プロジェクションを避けるべき場合
</div>

次のような場合は、プロジェクションの使用を避けることを検討してください。

* **複雑なデータ変換や多段階の ETL が必要な場合**: プロジェクション定義では `JOIN` 操作はサポートされず、多段階パイプラインを構築するために連結することもできません。また、ウィンドウ関数や複雑な `CASE` ステートメントなど、一部の SQL 機能も扱えません。プロジェクションを持つテーブルに対するクエリでは自由に `JOIN` できますが、プロジェクション自体は複雑なデータ変換には向いていません。
* **マテリアライズするデータを明示的に絞り込む必要がある場合**: プロジェクションでは、プロジェクション自体にマテリアライズされるデータを絞り込むための `WHERE` 句を定義に含めることはできません。
* **MergeTree 以外のテーブルエンジンを使用している場合**: プロジェクションを利用できるのは、`MergeTree` ファミリーのエンジンを使用するテーブルのみです。
* `FINAL` クエリが不可欠な場合: プロジェクションは `FINAL` クエリでは機能せず、`FINAL` クエリは重複排除のために使われることがあります。
* [並列レプリカ](/ja/products/cloud/features/infrastructure/parallel-replicas) が必要な場合: プロジェクションではサポートされていません。

<div id="summary">
  ## まとめ
</div>

materialized view とプロジェクションは、どちらもクエリの最適化やデータ変換に役立つ強力な手段です。一般に、これらは二者択一で考えるべきではありません。むしろ、相互に補完しながら使うことで、クエリの性能を最大限に引き出せます。したがって、ClickHouse で materialized view とプロジェクションのどちらを選ぶかは、最終的には具体的なユースケースとアクセスパターンによって決まります。

一般的な目安として、1 つ以上のソーステーブルからデータを集約してターゲットテーブルに格納したい場合や、大規模な複雑な変換を行いたい場合は、materialized view の利用を検討してください。materialized view は、コストの高い集計処理をクエリ実行時から挿入時へ移すのに非常に適しています。日次または月次のロールアップ、リアルタイムダッシュボード、データのサマリーに適した選択肢です。

一方、テーブルの主キー (ディスク上でのデータの物理的な並び順を決めるキー) に使われているカラムとは異なるカラムでフィルタするクエリを最適化したい場合は、プロジェクションを使うべきです。特に、テーブルの主キーをもはや変更できない場合や、アクセスパターンが主キーだけでは対応しきれないほど多様な場合に有効です。
