ユーザーからよく寄せられる質問の 1 つに、materialized view と プロジェクションのどちらを使うべきか、というものがあります。この記事では、この 2 つの主な違いと、 状況に応じてどちらを選ぶべきかを説明します。
主な違いの要約
materialized view とプロジェクションの比較
materialized viewを選ぶべき場合
- リアルタイムETLと多段データパイプラインに対応する場合: 複雑な変換や集計を実行する必要がある、または到着したデータをルーティングする必要があり、viewを連鎖させて複数段階にまたがる処理を行う可能性がある場合。
- 複雑な非正規化が必要な場合: 複数のソース (テーブル、サブクエリ、または辞書) のデータを、クエリに最適化された単一のテーブルに事前に結合する必要があり、特にリフレッシュ可能なマテリアライズドビューを使用した定期的なフルrefreshを許容できる場合。
- 明示的なスキーマ制御を行いたい場合: 事前計算された結果を格納するために、独自のスキーマとエンジンを持つ別個のターゲットテーブルが必要であり、データモデリングにより高い柔軟性を求める場合。
- インジェスト時にfilterしたい場合: データがmaterializedされる_前に_ filterする必要があり、ターゲットテーブルに書き込まれるデータ量を削減したい場合。
materialized viewを避けるべきケース
- ソースデータが頻繁に更新または削除される: ソーステーブルとターゲットテーブルの整合性を保つための追加の対策がないと、インクリメンタルmaterialized viewが古い状態になり、一貫性が失われる可能性があります。
- シンプルさと自動最適化を重視する: 個別のターゲットテーブルを管理したくない場合です。
プロジェクションを選ぶべき場合
- 単一テーブルのクエリを最適化したい: 主な目的が、別のソート順を用意したり、プライマリキーに含まれないカラムに対するフィルタを最適化したり、単一の基となるテーブルに対する集計を事前計算したりすることで、そのテーブルに対するクエリを高速化することである場合。
- クエリの透過性を求める: クエリを変更せずに元のテーブルを対象とし、指定したクエリに対して最適なデータレイアウトを ClickHouse に選択させたい場合。
プロジェクションを避けるべき場合
- 複雑なデータ変換や多段階の ETL が必要な場合: プロジェクション定義では
JOIN操作はサポートされず、多段階パイプラインを構築するために連結することもできません。また、ウィンドウ関数や複雑なCASEステートメントなど、一部の SQL 機能も扱えません。プロジェクションを持つテーブルに対するクエリでは自由にJOINできますが、プロジェクション自体は複雑なデータ変換には向いていません。 - マテリアライズするデータを明示的に絞り込む必要がある場合: プロジェクションでは、プロジェクション自体にマテリアライズされるデータを絞り込むための
WHERE句を定義に含めることはできません。 - MergeTree 以外のテーブルエンジンを使用している場合: プロジェクションを利用できるのは、
MergeTreeファミリーのエンジンを使用するテーブルのみです。 FINALクエリが不可欠な場合: プロジェクションはFINALクエリでは機能せず、FINALクエリは重複排除のために使われることがあります。- 並列レプリカ が必要な場合: プロジェクションではサポートされていません。