
2026/08/12 6:54
pg_clickhouse v0.10:サブクエリプッシュダウンと TPC-H クエリの 1000 倍高速化
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
修正済みサマリの提案
「pg_clickhouse v0.10.0 リリースは、クエリ・プッシュダウンを目的とした根本的なアーキテクチャの転換をもたらしました。これにより、TPC-H クエリのカバー範囲は 22 のうち 16 に拡大し(前版から 12 から増加)、Query Q17 のレイテンシは 3 秒以上からわずか 24 ミリ秒へと劇的に削減されました。この実現を可能にするため、ドライバは C++ から効率的なプレーン C クライアントライブラリ(
clickhouse-c)に変更され、ビルド時間/サイズの削減率 75% を達成するとともに、メモリ効率の高いストリーミング処理が可能になりました。今回の更新では、PostgreSQL の三値論理と ClickHouse の二値システムを IN オペレーターファミリー全体で統合するため、transform_null_in をハードコードしてゼロに固定し、ビルトイン関数のオプトイン型アクティベーションを導入することで意味論的なエラーを防ぎました。さらに、このリリースでは非効率的な SubPlan ノードを排除し、相関 EXISTS サブクエリを単一のステートメントとしてプッシュダウンするとともに、外国キーのスキャンごとに専用接続を設定することで重大な並行処理クラッシュを修正しました。加えて、v0.10 では多次元配列のサポート、新しい圧縮オプション、および高度な統計的アグリゲートが追加されました。ただし、ユーザーは非推奨となったバッチ処理オプションの廃止に適応する必要があり、また 6 つのクエリ(特に anti/semi-join 内部ネストされた join)についてはプッシュダウンされていないことを留意してください。」本文
pg_clickhouse v0.10.0: TPC-H 完全プッシュダウンの進捗とアーキテクチャの刷新
pg_clickhouse の継続的な投資の一環として、分析ワークロードにおけるプッシュダウン(Pushdown)カバレッジの向上が最優先事項です。当面の目標は TPC-H ベンチマークスイートの全問にわたる完全プッシュダウン です。2023 年 12 月の導入発表以来、大幅な進展を遂げました。
TPC-H スコアボードの進捗状況
v0.10.0 リリースに伴い、完全プッシュダウンされた TPC-H クエリは 22 問中 16 問に増加しました(前回より +4 問)。残りの未対応クエリは 6 問となりました。
劇的なパフォーマンス改善
以前非効率だった 3 つのクエリが完全プッシュダウンできるようになりました。これにより、ローカルでのサブクエリ評価を避け、ClickHouse が直接処理可能になりました。
| クエリ | PostgreSQL | pg_clickhouse 0.3 (推定) | pg_clickhouse 0.10 (現在) | プッシュダウン状態 |
|---|---|---|---|---|
| Q2 | 88 ms | 3,446 ms | 24 ms | ✔ (完全) |
| Q17 | 2,107 ms | 32,709 ms | 37 ms | ✔ (完全) |
| Q22 | 270 ms | 1,415 ms | 45 ms | ✼ (一部)* |
- (✔) クエリ全体が単一の外部スキャンとして実行。
- (✼) プッシュダウンは行われていますが、複数のリモートクエリが必要です(通常、外部スキャンと InitPlan スキャンの組み合わせ)。
Q17 の事例:
- 内容: 6M 行数(スケールファクター 1)に対し、相関付きサブクエリによる平均値計算(
をl_quantity
あたりに平均化)。part - 改善前: スケーリング時に 32.7 秒 かかる。
- 改善後: 完全プッシュダウンにより 37 ミリ秒 に短縮。
- 効果: 約 1,000 分の 1 の劇的改善。PostgreSQL ネイティブ(2.1 秒)よりも明確に高速化されています。
残りの課題:6 つの未対応クエリ
現在プッシュダウンされていないのは以下の 6 クエリです:Q13, Q15, Q16, Q18, Q20, Q21。
- Q16 / Q18 (前進あり): SQL 形状(
,IN
を反転結合として)のプッシュダウンは可能ですが、PostgreSQL がサブクエリを平坦化し、入力が**結合(JOIN)**となっている点が障害です。現在のデパサーは結合ツリーを両側で遡る処理ができません。NOT IN - Q15 / Q20 (同様の問題): 上記のバリエーションであり、これが次期ロードマップの主要な課題となります。
アーキテクチャと実装の詳細革新
1. SubPlan(サブプラン)のプッシュダウン
頭版機能により、「相関付き EXISTS サブクエリ」を単一の
LEFT SEMI JOIN として処理する学習が可能になりました。これにより、完全プッシュダウン数は 3 から 22 に劇的に増加しました。
- 仕組み:
ではEXPLAIN
ノードが残りますが(帳簿処理)、実際のSubPlan
はサブクエリを含む単一のステートメントとして ClickHouse に送信されます。Remote SQL - サポート範囲:
もNOT IN
として同様に扱えます。LEFT ANTI JOIN
実装例:ClickHouse 内でのサブクエリ処理
EXPLAIN (VERBOSE, COSTS OFF) SELECT s.sale_id, s.amount FROM sales s WHERE s.amount > (SELECT 1.5 * avg(s2.amount) FROM sales s2 WHERE s2.item_id = s.item_id) ORDER BY s.sale_id;
実行結果の要点:
ノードは存在しますが、比較的全部内容(サブクエリ含む)は 単一の Remote SQL ステートメント として送信されています。SubPlan expr_1- これにより Q2 のような構造も単一外部スキャン+リモートクエリの構成にできます。
⚠️ サーバーバージョンの制限: クリックハウス バージョン 25.8 未満ではこの形状をサポートしていないため、動作しません(フォールバック実行)。
2. NULL 値の安全性確保(三値論理 vs 二値論理)
ClickHouse の
IN は二値論理、PostgreSQL は三値論理を採用しているため、単純なプッシュダウンは危険です。
- リスク: PostgreSQL では
はx NOT IN (1, NULL)
にはならず、NULL が関与すると予期せぬ結果(静的逆転)を生じる可能性があります。TRUE
v0.10 の修正により、各発現の結果の消費方法を追跡し、整合性を保つための**防御的対策(Hedging)**が実装されました。
状況に応じたプッシュダウン戦略
| 状況 | プッシュダウン結果 | 動作説明 |
|---|---|---|
| NULL 値を含む場合 (例: ) | 文が追加される | ClickHouse 側で NULL をチェックし、Postgres の挙動(FALSE/NULL)を模倣します。 |
| NULL 値を含まない場合 (例: ) | ネイティブ として送信 | 追加のガードなしで最適に実行されます。 |
-- NULL がある場合:Guard が追加される EXPLAIN (VERBOSE, COSTS OFF) SELECT id FROM tnull WHERE xn NOT IN (1, NULL) ORDER BY id; -- Remote SQL: CASE WHEN ... THEN NULL ... END -- NULL のない場合:単純な IN として送信 EXPLAIN (VERBOSE, COSTS OFF) SELECT id FROM tnull WHERE xn NOT IN (1, 500) ORDER BY id; -- Remote SQL: xn NOT IN (1, 500)
- 一般化:
,IN
,NOT IN
,= ANY
など全てのスカラ/アレイ形式に適用(#317)。<\> ANY - 設定の注意: クリックハウスの二値論理仮定に基づいています。サーバーレベルの設定
がこの挙動を変更するため、pg_clickhouse 側ではtransform_null_in
をデフォルトに設定し、ガードが無効化されるのを防いでいます。pg_clickhouse.session_settings.transform_null_in = 0
3. バイナリドライバーの刷新 (clickhouse-c
への移行)
clickhouse-c古くからの
clickhouse-cpp ベースから、新しい C クライアント clickhouse-c(git サブモジュールとしてベンダー化)に全面置き換えました(#254)。
- メモリ効率: C++ の例外処理と Postgres エラー処理の混在によるクラッシュを防止。ブロック単位の結果ストリーミングにより、メモリの使用量が劇的に改善。
- ビルドサイズ: 依存ライブラリのビルド時間とサイズが 75% 以上削減。
- 通信プロトコル: HTTP ドライバーも ClickHouse ネイティブ形式をサポートし、古い TSV ベースの経路廃止(#328)。
設定は廃止(ネイティブデコーダーは常に curl チャンク単位でストリーミングするため)。fetch_size
- セキュリティ: TLS コントロールと明示的な圧縮サポート(none/lz4/zstd)の追加。
4. プッシュダウン可能な機能リストの拡大
関数、演算子、集合演算子の領域が大幅に拡大しました(詳細は CHANGELOG 参照)。
- 統計的・ソート順集合演算子:
,corr
,covar_pop/samp
など。percentile_cont/disc - パーティション単位演算子: 外部パーティション計算機能の強化。
- 文字列・日時処理:
, エンコーディング、間隔算術の拡張など。ltrim/rtrim/btrim - その他改善:
- ビルトイン関数のプッシュダウンを**オプトイン (#245)**にすることで、セマンティクスの整合性を担保(三角関数等の例外対応)。
統合による信頼性向上(並行スキャンの衝突防止、Use-After-Free バグ修正など)。clickhouse-c
追加された主要な機能
- JSON: ネイティブ JSON タイプのマッピング、パスアクセスオペレーターの追加。
- アレイ:
,array_cat
, スライス構文 (append
) 等の多数の関数対応。arr[L:U] - 集合演算子: ウィンドウ関数 (
,ROW_NUMBER
など) の完全セット対応、ブール値・文字列集約関数の追加。NTILE - ユーティリティ:
とclickhouse_query()
の新機能化(#309, #329)、バージョンレポート機能の追加。clickhouse_perform()
今後のロードマップと課題
現在、TPC-H クエリへの完全プッシュダウンには Q15, Q16, Q18, Q20 をブロックする「結合ツリー両側での制限」が残っています。これらが次の段階的なサブクエリプッシュダウンの鍵となります。
また、以下の機能も残りの課題としてリストアップされています:
- 未対応の PostgreSQL 関数の追加
- 軽量な
/DELETE
のプッシュダウンUPDATE
のプッシュダウンUNION
これらのクリアが完了するまで、pg_clickhouse の分析パフォーマンス向上の旅はまだ続きます。