リフレッシュ可能なマテリアライズドビュー
リフレッシュ可能なマテリアライズドビューは、従来のOLTPデータベースにおけるマテリアライズドビューに概念的に類似しており、特定のクエリの結果を保存し、迅速な取得を可能にすることで、リソース集約型のクエリを繰り返し実行する必要を減らします。ClickHouseの増分マテリアライズドビューとは異なり、これは全データセットに対して定期的にクエリを実行する必要があります。その結果は、クエリ用にターゲットテーブルに保存されます。この結果セットは理論的には元のデータセットよりも小さいため、その後のクエリはより速く実行されることが期待されます。
以下の図は、リフレッシュ可能なマテリアライズドビューの動作を説明します。

次のビデオもご覧いただけます:
リフレッシュ可能なマテリアライズドビューはいつ使用すべきか?
ClickHouseの増分マテリアライズドビューは非常に強力で、リフレッシュ可能なマテリアライズドビューで使用されるアプローチよりも通常はスケールが良好です。特に、単一のテーブルに対して集計を実行する必要がある場合で、そのデータの各ブロックに対してのみ集計を行い、最終テーブルで増分状態をマージすることにより、クエリはデータのサブセットでのみ実行されます。この方法は数ペタバイトのデータにまでスケールし、通常は好ましい方法です。
しかし、この増分プロセスが必要ない、あるいは適用できないユースケースもあります。いくつかの問題は増分アプローチと互換性がなく、リアルタイム更新を必要としないため、定期的な再構築がより適切です。たとえば、複雑な結合を使用しているため、完全なデータセットに対するビューの完全な再計算を定期的に実行したい場合があります。
リフレッシュ可能なマテリアライズドビューは、非正規化などのタスクを実行するバッチプロセスを実行できます。リフレッシュ可能なマテリアライズドビュー間に依存関係を作成することができ、あるビューが別のビューの結果に依存し、完了した後にのみ実行されるようにできます。これは、スケジュールされたワークフローやdbtジョブなどのシンプルなDAGを置き換えることができます。リフレッシュ可能なマテリアライズドビュー間の依存関係の設定方法については、CREATE VIEW、
Dependencies
セクションをご覧ください。
リフレッシュ可能なマテリアライズドビューをどのようにリフレッシュしますか?
リフレッシュ可能なマテリアライズドビューは、作成時に定義されたインターバルで自動的にリフレッシュされます。 たとえば、以下のマテリアライズドビューは毎分リフレッシュされます:
マテリアライズドビューを強制的にリフレッシュしたい場合は、SYSTEM REFRESH VIEW
句を使うことができます:
ビューをキャンセル、停止、または開始することもできます。 詳細については、リフレッシュ可能なマテリアライズドビューの管理のドキュメントをご覧ください。
リフレッシュ可能なマテリアライズドビューは最後にいつリフレッシュされましたか?
リフレッシュ可能なマテリアライズドビューが最後にリフレッシュされた時期を知るには、次のようにsystem.view_refreshes
システムテーブルをクエリします:
リフレッシュレートを変更するにはどうすればよいですか?
リフレッシュ可能なマテリアライズドビューのリフレッシュレートを変更するには、ALTER TABLE...MODIFY REFRESH
構文を使用します。
その後、リフレッシュ可能なマテリアライズドビューが最後にリフレッシュされた時期を確認するために、リフレッシュ可能なマテリアライズドビューは最後にいつリフレッシュされましたか?のクエリを使用できます:
新しい行を追加するための APPEND
の使用
APPEND
機能を使用すると、ビュー全体を置き換える代わりに、テーブルの末尾に新しい行を追加できます。
この機能の一例は、特定の時点での値のスナップショットをキャプチャすることです。たとえば、KafkaやRedpandaなどのストリーミングデータプラットフォームからのメッセージのストリームによって人口が増加したevents
テーブルを考えてみましょう。
このデータセットにはuuid
カラムに4096
の値があります。次のクエリを記述して、合計カウントが最も高いものを見つけることができます:
10秒ごとに各uuid
のカウントをキャプチャし、events_snapshot
という新しいテーブルに保存したいとしましょう。events_snapshot
のスキーマは次のようになります:
次に、次のようにこのテーブルをポピュレートするためのリフレッシュ可能なマテリアライズドビューを作成します:
その後、特定のuuid
のカウントを時間経過とともに取得するためにevents_snapshot
をクエリできます:
例
リフレッシュ可能なマテリアライズドビューをいくつかの例のデータセットで使用する方法を見てみましょう。
Stack Overflow
非正規化データガイドでは、Stack Overflowデータセットを使用してデータを非正規化するさまざまな技術を示しています。votes
、users
、badges
、posts
、およびpostlinks
というテーブルにデータをポピュレートします。
そのガイドでは、次のクエリでpostlinks
データセットをposts
テーブルに非正規化する方法を示しました:
このデータをposts_with_links
テーブルに1回挿入する方法を示しましたが、本番システムではこの操作を定期的に実行したいでしょう。
posts
テーブルとpostlinks
テーブルはどちらも更新される可能性があります。したがって、増分マテリアライズドビューを使用してこの結合を実装するのではなく、このクエリを設定された間隔で実行するようにスケジュールし、結果をpost_with_links
テーブルに保存するのが十分かもしれません。
ここで、リフレッシュ可能なマテリアライズドビューが役立ちます。次のクエリで作成できます:
このビューは即座に実行され、以降は設定された間隔ごとに実行され、ソーステーブルの更新が反映されるようになります。重要なことは、クエリが再実行されると、結果セットが原子的かつ透過的に更新されることです。
ここでの構文は、REFRESH
句を含む限り、増分マテリアライズドビューと同じです:
IMDb
dbtとClickHouseの統合ガイドでは、actors
、directors
、genres
、movie_directors
、movies
、およびroles
というテーブルでIMDbデータセットをポピュレートしました。
次のクエリを使用して、各俳優の要約を計算できます。ムービーの出現頻度によって並べ替えます。
結果を返すのにそれほど時間はかかりませんが、さらに迅速で計算負荷の少ないものにしたいとしましょう。 このデータセットは絶えず更新されており、映画も新しい俳優や監督とともに常にリリースされています。
リフレッシュ可能なマテリアライズドビューの出番です。結果用のターゲットテーブルをまず作成しましょう:
次に、ビューを定義できます:
このビューは即座に実行され、その後、設定どおりに毎分実行され、ソーステーブルの更新が反映されるようになります。俳優の要約を取得するための前のクエリが、文法的に簡素化され、著しく高速になります!
新しい俳優 "Clicky McClickHouse" をソースデータに追加すると、彼は多くの映画に出演したことになります!
60秒も経たないうちに、ターゲットテーブルはClickyの俳優としての多才な側面を反映するために更新されます: