Skip to main content
すべてのクイックスタート
リアルタイムアナリティクスデータウェアハウジングオブザーバビリティAI/MLCloudOss

前提条件

To successfully follow this guide, you’ll need the following: また、このガイドはそこで作成した uk_price_paid テーブルをそのまま使用するため、Create your first MergeTree table クイックスタートも完了しておく必要があります。

作成するもの

MergeTree の クイックスタート では、テーブルが (postcode, addr1, addr2) でソートされているため、town または countyuk_price_paid をクエリするにはテーブル全体のスキャンが必要になることを確認しました。 この クイックスタート では、その問題を解決するために、同じデータを (town, date) でソートして保存する materialized view を作成し、元のテーブルを変更せずに town による高速なルックアップを可能にします。 最後には、materialized view が insert trigger としてどのように機能するか、既存データをどのようにバックフィルするか、そしてデータを 2 回保存することによるディスク容量のトレードオフを理解できるようになります。
1

materialized view が必要な理由を理解する

uk_price_paid テーブルは (postcode, addr1, addr2) でソートされています。つまり、postcodeaddr1addr2 で絞り込む場合、ClickHouse は大きなデータ block を読み飛ばせますが、town で絞り込むクエリでは、3,000 万行すべてをスキャンしなければなりません。別の ORDER BY を持つ 2 つ目のテーブルを作成することもできますが、その場合は新しいデータが届くたびに、両方のテーブルに insert する必要があります。materialized view を使えば、これを自動化できます。source table への insert を監視し、行を変換して、宛先テーブルへ自動的に書き込みます。materialized view は insert trigger のようなものと考えてください。source table に行が insert されるたびに、MV の SELECT クエリが新しい block に対して実行され、その結果が宛先テーブルに insert されます。
2

宛先テーブルを作成する

materialized view では、出力の保存先が必要です。これは通常の MergeTree テーブルであり、スキーマ、ORDER BYPARTITION BY を完全に自由に制御できます。町単位のクエリに必要なカラムだけを含む、(town, date) でソートされたテーブルを作成します:
このテーブルに特別な点はなく、標準的なMergeTreeテーブルです。次に作成するmaterialized viewは、単にデータをこのテーブルにルーティングするだけです。テーブルが作成されたことを確認します:
3

materialized view を作成する

次に、ソーステーブル (uk_price_paid) と宛先テーブル (uk_price_paid_by_town) を結び付ける materialized view を作成します。
TO uk_price_paid_by_town 句は、SELECT の出力を宛先テーブルに書き込むよう ClickHouse に指示します。以後、uk_price_paid に行が挿入されるたびに、この MV がトリガーされ、変換後の行を uk_price_paid_by_town に挿入します。重要な注意点があります。materialized view がトリガーされるのは inserts のときだけです。ソーステーブルの行を削除または更新しても、宛先テーブルはそれを認識しません。つまり、MV は削除や更新とは同期されません。そのような同期が必要な場合は、代わりに projections の使用を検討してください。
4

既存データをバックフィルする

materialized view が処理するのは 今後の 挿入のみです。uk_price_paid にすでに存在する 3,000 万行は、MV が作成される前に挿入されていたため、宛先テーブルは現在空のままです。手動でバックフィルします:
これは宛先テーブルに直接挿入されます。このステップでは MV は関与しません。完了したら、行数が一致していることを確認してください:
どちらのテーブルも、行数は同じである必要があります。
5

materialized viewの宛先テーブルをクエリする

次に、宛先テーブルに対して town で絞り込むクエリを実行し、ソーステーブルを直接クエリした結果と比較します。まず、ソーステーブルをクエリします。
クエリ統計を確認してください。town がソーステーブルの ORDER BY に含まれていないため、3,000万行すべてが読み込まれます。次に、materialized view の宛先テーブルに対して同じクエリを実行します。
クエリ統計をもう一度確認してください。宛先テーブルは (town, date) でソートされているため、ClickHouse は LONDON に一致しないデータをすべてスキップでき、読み取る行数が大幅に減ります。作成されたものを確認するには、SHOW TABLES を実行します。
uk_price_paid_by_town (宛先テーブル) と uk_price_paid_by_town_mv (ビュー) の両方が表示されます。CREATE MATERIALIZED VIEW ... TO を使用しているため、宛先テーブル名は自分で指定できます。TO 句を省略すると、ClickHouse は暗黙的な名前の宛先テーブル (.inner.xxx) を作成しますが、これは直接扱いにくくなります。 そのため、materialized view は TO 句を使って作成することを推奨します。
6

データが二重に保存されていることを確認する

materialized view を使うと、追加のディスク容量と引き換えに、より高速に読み取れます。各テーブルがどれだけの容量を使用しているかを確認するには、system.parts をクエリします。
データは物理的に2回保存されます。1つは (postcode, addr1, addr2) でソートされた uk_price_paid に、もう1つは (town, date) でソートされた uk_price_paid_by_town に保存されます。これが基本的なトレードオフです。つまり、異なるアクセスパターンでの読み取りを高速化する代わりに、より多くのディスク容量を使用します。宛先テーブルは、含まれるカラム数が少なく、(town, date) のソート順では元のデータとは異なる圧縮が行われる可能性があるため、ディスク上のサイズが小さくなる場合があります。

次のステップ

このクイックスタートでは、元のテーブルを変更することなく、異なるソート順で英国の不動産売買データを保存する materialized view を作成し、町ごとの高速なルックアップを可能にしました。また、MV は insert trigger として機能すること、既存データは手動でバックフィルする必要があること、そしてそのトレードオフとして追加のディスク容量が必要になることも学びました。 続けて、以下のクイックスタートをご覧ください。 あるいは、リファレンスドキュメントでさらに詳しく確認できます。
ClickHouse Academy — Master ClickHouse with expert-designed training for every skill level

Check out the ClickHouse academy for on-demand and live training

Last modified on June 10, 2026