メインコンテンツまでスキップ
メインコンテンツまでスキップ

リフレッシュ可能なマテリアライズドビュー

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

以下の図は、リフレッシュ可能なマテリアライズドビューの動作を説明します。

リフレッシュ可能なマテリアライズドビューの図

次のビデオもご覧いただけます:

リフレッシュ可能なマテリアライズドビューはいつ使用すべきか?

ClickHouseの増分マテリアライズドビューは非常に強力で、リフレッシュ可能なマテリアライズドビューで使用されるアプローチよりも通常はスケールが良好です。特に、単一のテーブルに対して集計を実行する必要がある場合で、そのデータの各ブロックに対してのみ集計を行い、最終テーブルで増分状態をマージすることにより、クエリはデータのサブセットでのみ実行されます。この方法は数ペタバイトのデータにまでスケールし、通常は好ましい方法です。

しかし、この増分プロセスが必要ない、あるいは適用できないユースケースもあります。いくつかの問題は増分アプローチと互換性がなく、リアルタイム更新を必要としないため、定期的な再構築がより適切です。たとえば、複雑な結合を使用しているため、完全なデータセットに対するビューの完全な再計算を定期的に実行したい場合があります。

リフレッシュ可能なマテリアライズドビューは、非正規化などのタスクを実行するバッチプロセスを実行できます。リフレッシュ可能なマテリアライズドビュー間に依存関係を作成することができ、あるビューが別のビューの結果に依存し、完了した後にのみ実行されるようにできます。これは、スケジュールされたワークフローやdbtジョブなどのシンプルなDAGを置き換えることができます。リフレッシュ可能なマテリアライズドビュー間の依存関係の設定方法については、CREATE VIEWDependenciesセクションをご覧ください。

リフレッシュ可能なマテリアライズドビューをどのようにリフレッシュしますか?

リフレッシュ可能なマテリアライズドビューは、作成時に定義されたインターバルで自動的にリフレッシュされます。 たとえば、以下のマテリアライズドビューは毎分リフレッシュされます:

マテリアライズドビューを強制的にリフレッシュしたい場合は、SYSTEM REFRESH VIEW句を使うことができます:

ビューをキャンセル、停止、または開始することもできます。 詳細については、リフレッシュ可能なマテリアライズドビューの管理のドキュメントをご覧ください。

リフレッシュ可能なマテリアライズドビューは最後にいつリフレッシュされましたか?

リフレッシュ可能なマテリアライズドビューが最後にリフレッシュされた時期を知るには、次のようにsystem.view_refreshesシステムテーブルをクエリします:

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

リフレッシュ可能なマテリアライズドビューのリフレッシュレートを変更するには、ALTER TABLE...MODIFY REFRESH構文を使用します。

その後、リフレッシュ可能なマテリアライズドビューが最後にリフレッシュされた時期を確認するために、リフレッシュ可能なマテリアライズドビューは最後にいつリフレッシュされましたか?のクエリを使用できます:

新しい行を追加するための APPEND の使用

APPEND機能を使用すると、ビュー全体を置き換える代わりに、テーブルの末尾に新しい行を追加できます。

この機能の一例は、特定の時点での値のスナップショットをキャプチャすることです。たとえば、KafkaRedpandaなどのストリーミングデータプラットフォームからのメッセージのストリームによって人口が増加したeventsテーブルを考えてみましょう。

このデータセットにはuuidカラムに4096の値があります。次のクエリを記述して、合計カウントが最も高いものを見つけることができます:

10秒ごとに各uuidのカウントをキャプチャし、events_snapshotという新しいテーブルに保存したいとしましょう。events_snapshotのスキーマは次のようになります:

次に、次のようにこのテーブルをポピュレートするためのリフレッシュ可能なマテリアライズドビューを作成します:

その後、特定のuuidのカウントを時間経過とともに取得するためにevents_snapshotをクエリできます:

リフレッシュ可能なマテリアライズドビューをいくつかの例のデータセットで使用する方法を見てみましょう。

Stack Overflow

非正規化データガイドでは、Stack Overflowデータセットを使用してデータを非正規化するさまざまな技術を示しています。votesusersbadgesposts、およびpostlinksというテーブルにデータをポピュレートします。

そのガイドでは、次のクエリでpostlinksデータセットをpostsテーブルに非正規化する方法を示しました:

このデータをposts_with_linksテーブルに1回挿入する方法を示しましたが、本番システムではこの操作を定期的に実行したいでしょう。

postsテーブルとpostlinksテーブルはどちらも更新される可能性があります。したがって、増分マテリアライズドビューを使用してこの結合を実装するのではなく、このクエリを設定された間隔で実行するようにスケジュールし、結果をpost_with_linksテーブルに保存するのが十分かもしれません。

ここで、リフレッシュ可能なマテリアライズドビューが役立ちます。次のクエリで作成できます:

このビューは即座に実行され、以降は設定された間隔ごとに実行され、ソーステーブルの更新が反映されるようになります。重要なことは、クエリが再実行されると、結果セットが原子的かつ透過的に更新されることです。

注記

ここでの構文は、REFRESH句を含む限り、増分マテリアライズドビューと同じです:

IMDb

dbtとClickHouseの統合ガイドでは、actorsdirectorsgenresmovie_directorsmovies、およびrolesというテーブルでIMDbデータセットをポピュレートしました。

次のクエリを使用して、各俳優の要約を計算できます。ムービーの出現頻度によって並べ替えます。

結果を返すのにそれほど時間はかかりませんが、さらに迅速で計算負荷の少ないものにしたいとしましょう。 このデータセットは絶えず更新されており、映画も新しい俳優や監督とともに常にリリースされています。

リフレッシュ可能なマテリアライズドビューの出番です。結果用のターゲットテーブルをまず作成しましょう:

次に、ビューを定義できます:

このビューは即座に実行され、その後、設定どおりに毎分実行され、ソーステーブルの更新が反映されるようになります。俳優の要約を取得するための前のクエリが、文法的に簡素化され、著しく高速になります!

新しい俳優 "Clicky McClickHouse" をソースデータに追加すると、彼は多くの映画に出演したことになります!

60秒も経たないうちに、ターゲットテーブルはClickyの俳優としての多才な側面を反映するために更新されます: