JOIN を完全にサポートしています。パフォーマンスを最大限に高めるには、このガイドにある JOIN 最適化の推奨事項に従うことをおすすめします。
- 最適なパフォーマンスを得るには、クエリ内の
JOINの数をできるだけ減らすことを目指してください。特に、ミリ秒単位の性能が求められるリアルタイム分析ワークロードでは重要です。1 つのクエリでのJOINは最大 3~4 個を目安にしてください。データモデリングのセクションでは、非正規化、Dictionaries、materialized view など、JOIN を最小限に抑えるためのさまざまな手法を詳しく説明しています。 - ClickHouse 24.12 以降では、クエリプランナーが 2 テーブルの JOIN を自動的に並べ替え、最適なパフォーマンスが得られるよう小さいテーブルを右側に配置します。バージョン 25.9 では、これが 3 つ以上のテーブルを JOIN するクエリの JOIN 順序の最適化にも拡張されました。
- クエリでダイレクト JOIN、つまり以下に示す
LEFT ANY JOINが必要な場合は、可能であれば Dictionaries を使用することを推奨します。
- INNER JOIN を行う場合は、
IN句を使ったサブクエリとして記述したほうが、より効率的なことがよくあります。次のクエリを見てください。これらは機能的には同等で、どちらも質問では ClickHouse に言及していないものの、commentsでは言及しているpostsの数を求めます。
INNER JOIN ではなく ANY INNER JOIN を使用している点に注意してください。
この JOIN はサブクエリを使って書き換えることができ、パフォーマンスを大幅に改善できます。
JOIN するデータ量を最小限に抑えられます。以下の例では、2020 年以降の Java 関連の投稿に対する賛成票数を計算したいとします。
より大きなテーブルを左側に置いた単純なクエリは、56 秒で完了します:
INNER JOIN をサブクエリに移し、外側と内側の両方のクエリにフィルタを適用したままにすることで、さらに改善できます。
JOIN アルゴリズムの選択
これらのアルゴリズムによって、JOIN クエリの計画方法と実行方法が決まります。デフォルトでは、ClickHouse は使用される JOIN type と strictness、および結合対象テーブルの engine に応じて、direct または hash join アルゴリズムを使用します。あるいは、リソースの可用性と使用状況に応じて、実行時に使用する JOIN アルゴリズムを適応的に選択し、動的に変更するように ClickHouse を設定することもできます。
join_algorithm=auto の場合、ClickHouse はまず hash join アルゴリズムを試し、そのアルゴリズムのメモリ制限を超えると、実行中に partial merge join へ切り替えます。どのアルゴリズムが選択されたかは、トレースログで確認できます。また、ClickHouse では join_algorithm 設定を使って、使用する JOIN アルゴリズムを明示的に指定することもできます。
各 join アルゴリズムでサポートされる JOIN type を以下に示します。最適化を行う前に、これを考慮してください。
各
JOIN アルゴリズムの完全な詳細説明は こちら を参照してください。長所、短所、スケーリング特性についても説明しています。
適切な JOIN アルゴリズムの選択は、メモリとパフォーマンスのどちらを優先して最適化したいかによって異なります。
JOIN パフォーマンスの最適化
-
(1) 右側テーブルのデータを、たとえば Dictionary のようなインメモリの低レイテンシなキー・バリュー・データ構造に事前ロードでき、JOIN キーが基盤となるキー・バリュー・ストレージのキー attribute と一致し、さらに
LEFT ANY JOINのセマンティクスで十分である場合は、direct join を適用できます。これは最速のアプローチです。 - (2) テーブルの物理的な行順序が JOIN キーのソート順と一致している場合は、状況によります。この場合、full sorting merge join はソートフェーズを省略できるため、メモリ使用量を大幅に削減でき、さらにデータサイズや JOIN キー値の分布によっては、一部のハッシュ結合アルゴリズムよりも高速に実行できることがあります。
- (3) 右側テーブルが、parallel hash join の追加のメモリ使用量オーバーヘッドを考慮してもメモリに収まる場合は、このアルゴリズム、または hash join のほうが高速なことがあります。これは、データサイズ、データ型、および JOIN キーのキーカラムの値分布に依存します。
- (4) 右側テーブルがメモリに収まらない場合も、やはり状況によります。ClickHouse には、メモリ容量に縛られない JOIN アルゴリズムが 3 つあります。これら 3 つはいずれも中間データを一時的にディスクに spill します。Full sorting merge join と partial merge join では、事前にデータをソートする必要があります。一方、Grace Hash Join はデータからハッシュテーブルを構築します。データ量、データ型、および JOIN キーのキーカラムの値分布によっては、データをソートするよりもハッシュテーブルを構築するほうが速い場合があります。逆も同様です。
メモリ使用量の最適化
- (1) テーブルの物理的な行順序が join キーのソート順序と一致している場合、full sorting merge join のメモリ使用量は最小になります。さらに、ソートフェーズが無効になるため、join の速度も良好です。
- (2) Grace Hash Join は、join 速度を犠牲にする代わりに、多数のバケットを設定することで、メモリ使用量を非常に低く抑えるよう調整できます。partial merge join は、意図的にメインメモリの使用量を低く抑えるよう設計されています。外部ソートを有効にした full sorting merge join は、一般に partial merge join より多くのメモリを使用します (行順序がキーのソート順序と一致しない場合) 。その代わり、join の実行時間は大幅に改善されます。