メインコンテンツへスキップ
この記事では、遅延マテリアライゼーションの仕組みと、それが ClickHouse の I/O 最適化全体の中でどのような位置づけにあるかを説明します。 また、遅延マテリアライゼーションによってクエリ性能が向上することを示す実例も紹介します。
バージョン 25.4 以降で利用可能遅延マテリアライゼーションは ClickHouse バージョン 25.4 で導入され、デフォルトで有効になっています。

概要

ClickHouse では長年にわたり、I/O を徹底的に削減するための多層的な最適化が段階的に導入されてきました。 これらの手法が、その高速性と効率性の基盤となっています。 上記の I/O 最適化によって読み取るデータ量は大幅に減らせますが、それでも WHERE 句を通過した行については、ソート、集約、LIMIT などの処理を実行する前に、すべてのカラムを読み込むことが前提になっています。では、一部のカラムはもっと後の段階まで不要だったり、WHERE 句を通過しても実際にはまったく使われなかったりする場合はどうでしょうか。 そこで登場するのが遅延マテリアライゼーションです。これは、I/O 最適化の仕組みを完成させる独立した拡張です。
  • 索引と PREWHERE を組み合わせることで、WHERE 句のカラムフィルターに一致する行だけが処理されるようになります。
  • 遅延マテリアライゼーションはこれをさらに進め、クエリ実行計画で実際に必要になるまでカラムの読み取りを遅らせます。 フィルタリング後であっても、次の処理 - たとえばソート - に必要なカラムだけがすぐに読み込まれます。 それ以外は後回しにされ、LIMIT があるため、多くの場合は最終結果を生成するのに必要な分だけしか読み込まれません。 このため、遅延マテリアライゼーションは Top N クエリで特に効果的です。最終結果に必要なのが、特定の、しかもしばしば大きなカラムからのごく少数の行だけであるケースが多いためです。

実例

遅延マテリアライゼーションをより深く理解するには、ブログ記事 “ClickHouse gets lazier (and faster): Introducing lazy materialization” を強くお勧めします。以下の例は前述のブログ記事から引用したもので、遅延マテリアライゼーションによって ClickHouse クエリの実行時間が 219 秒からわずか 139 ミリ秒まで短縮されること (1576 倍の高速化) を示すため、ここに再掲しています。 索引と PREWHERE の恩恵を受けるには、クエリにフィルターが必要です。索引には主キーのカラムに対するフィルターが、PREWHERE には任意のカラムに対するフィルターが必要になります。 遅延マテリアライゼーションはその上に自然に重ねて適用できますが、前述のほかの最適化とは異なり、カラムフィルターがまったくないクエリでも高速化できます。 次のクエリ例では、日付、製品、評価、認証済みかどうかに関係なく、Amazon レビューのうち「参考になった」票の数が最も多いものを探し、上位 3 件についてタイトル、見出し、本文全文を返します。 まず、遅延マテリアライゼーションを無効にした状態で、クエリを実行します (コールドなファイルシステムキャッシュを使用し、query_plan_optimize_lazy_materialization を使用) :
Query
Response
次に、クエリを再度実行します (今回もファイルシステムキャッシュはコールドな状態です) 。ただし今度は、遅延マテリアライゼーションを有効にして実行します:
Query
通常、遅延マテリアライゼーションの恩恵を受けるために query_plan_optimize_lazy_materialization = true を明示的に設定する必要はありません。 デフォルトで有効になっています。
Response
遅延マテリアライゼーションをオフにした場合とオンにした場合のパフォーマンスの違いを見てみましょう。

クエリ実行計画で遅延マテリアライゼーションを確認する方法

前のクエリで遅延マテリアライゼーションが使われているかどうかは、EXPLAIN 句を使用してクエリの論理実行計画を確認することで確認できます。
オペレータープランは下から上に読むことができ、ClickHouse が 3 つの大きな String カラムの読み取りを、ソートと件数制限の後まで遅延させていることを確認できます。
最終更新日 2026年7月1日