メインコンテンツへスキップ
リフレッシャブルmaterialized view は、概念的には従来の OLTP データベースにおける materialized view と似ており、指定したクエリの結果を保存することで高速な取得を可能にし、リソースを大量に消費するクエリを繰り返し実行する必要を減らします。ClickHouse の インクリメンタルmaterialized view とは異なり、こちらはデータセット全体に対してクエリを定期的に実行する必要があり、その結果はクエリ用のターゲットテーブルに保存されます。理論上、この result set は元のデータセットよりも小さくなるため、後続のクエリをより高速に実行できます。 次の図は、リフレッシャブルmaterialized viewの動作を示しています。 次のビデオもご覧いただけます。

リフレッシャブルmaterialized viewはどのような場合に使用すべきですか?

ClickHouseのインクリメンタルmaterialized viewは非常に強力で、通常はリフレッシャブルmaterialized viewで用いられるアプローチよりもはるかに高いスケーラビリティを発揮します。特に、単一テーブルに対する集約を実行する必要がある場合は、その傾向が顕著です。データの各ブロックが挿入されるたびにその集約のみを計算し、最終テーブルでインクリメンタルな状態をマージすることで、クエリが実行されるのは常にデータの一部に対してだけになります。この方法はPB級のデータまでスケール可能で、通常はこちらが推奨されます。 ただし、このインクリメンタルな処理が不要、または適用できないユースケースもあります。インクリメンタルなアプローチに適さない問題もあれば、リアルタイム更新を必要とせず、定期的な再構築の方が適しているケースもあります。たとえば、複雑な結合を使用しているためインクリメンタルなアプローチには適さないビューについて、データセット全体を対象に定期的に完全な再計算を行いたい場合があります。
リフレッシャブルmaterialized viewでは、非正規化のようなタスクを実行するバッチ処理を実行できます。リフレッシャブルmaterialized view間には依存関係を作成でき、あるビューが別のビューの結果に依存し、その完了後にのみ実行されるようにできます。これにより、スケジュールされたワークフローや、dbt job のような単純なDAGを置き換えられます。リフレッシャブルmaterialized view間の依存関係の設定方法について詳しくは、CREATE VIEWDependencies セクションを参照してください。

リフレッシャブルmaterialized viewをリフレッシュするにはどうすればよいですか?

リフレッシャブルmaterialized viewは、作成時に定義した間隔で自動的にリフレッシュされます。 たとえば、次のmaterialized viewは1分ごとにリフレッシュされます。
materialized view を強制的にリフレッシュするには、SYSTEM REFRESH VIEW 句を使用できます。
ビューはキャンセル、停止、開始することもできます。 詳しくは、リフレッシャブルmaterialized viewの管理のドキュメントを参照してください。

リフレッシャブルmaterialized view が最後にリフレッシュされたのはいつですか?

リフレッシャブルmaterialized view が最後にいつリフレッシュされたかを確認するには、以下のように system.view_refreshes システムテーブルをクエリします。

リフレッシュ間隔を変更するにはどうすればよいですか?

リフレッシャブルmaterialized viewのリフレッシュ間隔を変更するには、ALTER TABLE...MODIFY REFRESH構文を使用します。
それが完了したら、リフレッシャブルmaterialized view が最後に更新されたのはいつですか? のクエリを使って、レートが更新されたことを確認できます:

APPEND を使用して新しい行を追加する

APPEND 機能を使うと、ビュー全体を置き換えるのではなく、テーブルの末尾に新しい行を追加できます。 この機能の用途の 1 つは、ある時点における値のスナップショットを取得することです。たとえば、KafkaRedpanda、またはその他のストリーミングデータプラットフォームからのメッセージストリームが events テーブルに取り込まれている状況を考えてみましょう。
このデータセットのuuidカラムには、4096個の値があります。合計数が最も多いものを見つけるには、次のクエリを実行できます。
uuid の件数を 10 秒ごとに取得し、events_snapshot という新しいテーブルに保存するとします。events_snapshot のスキーマは次のようになります。
次に、このテーブルにデータを格納するためのリフレッシャブルmaterialized viewを作成できます。
次に、特定の uuid について、events_snapshot をクエリして時間ごとの件数を取得できます。

それでは、いくつかの例となるデータセットを使って、リフレッシャブルmaterialized viewの使い方を見ていきましょう。

Stack Overflow

データの非正規化ガイドでは、Stack Overflow データセットを使ってデータを非正規化するさまざまな手法を紹介しています。データは次のテーブルに格納します: votesusersbadgespostspostlinks そのガイドでは、次のクエリを使って postlinks データセットを posts テーブルに非正規化する方法を示しました。
次に、このデータを posts_with_links テーブルに一回限りで挿入する方法を示しましたが、本番環境ではこの処理を定期的に実行したいところです。 posts テーブルと postlinks テーブルは、どちらも更新される可能性があります。そのため、インクリメンタルmaterialized view を使ってこの join を実装しようとするより、このクエリを一定間隔、たとえば1時間ごとに実行するようスケジュールし、その結果を post_with_links テーブルに保存するだけで十分な場合があります。 ここで役立つのがリフレッシャブルmaterialized view で、次のクエリで作成できます。
このviewは、設定どおりにまず直ちに実行され、その後は1時間ごとに実行されるため、ソーステーブルへの更新が確実に反映されます。重要なのは、クエリが再実行されると、結果セットがアトミックかつ透過的に更新されることです。
ここでの構文はインクリメンタルmaterialized viewと同一ですが、REFRESH句を含める点が異なります。

IMDb

dbt と ClickHouse のインテグレーションガイドでは、IMDb データセットに actorsdirectorsgenresmovie_directorsmoviesroles の各テーブルを取り込みました。 次に、以下のクエリを使用して、各俳優の概要を映画出演数の多い順に集計できます。
結果が返るまでにそれほど時間はかかりませんが、さらに高速化し、計算コストも抑えたいとしましょう。 このデータセットも絶えず更新されると考えてください。新しい俳優や監督が次々に登場し、新作映画も継続的に公開されます。 そこでリフレッシャブルmaterialized viewの出番です。まずは、結果を格納するターゲットテーブルを作成しましょう。
それでは、ビューを定義します:
このビューは、ソーステーブルへの更新が反映されるよう、設定どおりに直ちに実行され、その後は1分ごとに実行されます。先ほどの俳優の要約を取得するクエリは、構文がよりシンプルになり、実行速度も大幅に向上します!
仮に、数多くの映画に出演している新しい俳優 “Clicky McClickHouse” をソースデータに追加するとします!
60秒も経たないうちに、Clickyの出演作の多さが反映されるようターゲットテーブルが更新されます:
最終更新日 2026年7月1日