Skip to content

ClickHouse リリース 26.3

neutral avatar 400804ae96
ClickHouse
2026年4月7日 · 28分で読む

また新しい月が巡り、新たなリリースの時期がやってきました!

ClickHouse 26.3 contains 27 new features 🌷 40 performance optimizations 🐇 202 bug fixes 🐝

今回のリリースでは、非同期挿入のデフォルト有効化、ANTI、SEMI、FULL に対する JOIN 順序の最適化、マテリアライズド CTE などが導入されています!

新しいコントリビューター

26.3 のすべての新しいコントリビューターを心から歓迎します!ClickHouse コミュニティの成長にはいつも身が引き締まる思いであり、ClickHouse の普及を支えてくださる皆様の貢献に常に感謝しています。

新しいコントリビューターのお名前は以下のとおりです。

Alex Soffronow-Pagonidis, Alexey Smirnov, Amy Chen, Andrii Beskomornyi, Artem Brustovetskii, Artem Kytkin, Caio Ishizaka Costa, Cursor Agent, Daniel Q, Den Kalantaevskii, Desel72, Enric Calabuig, Finn, Fisnik Kastrati, François Martin, Herman Schaaf, JIaQi Tang, Maksim Kozlov, Nazarii Piontko, NeedmeFordev, Onyx2406, Riyane El Qoqui, Semen Checherinda, Vasily Chekalkin, Victor Zhou, Vikash, Yash, lioshik, martinfrancois, mcalfin, paf91, spider-yamet, tanner-bruce, vyalamar, wangzhibo

ヒント: このリストをどのように生成しているか興味がある方は… こちら をご覧ください。

プレゼンテーションのスライド もご覧いただけます。

マテリアライズド CTE

コントリビューター: Dmitry Novik

26.3 リリースでは MATERIALIZED 句が導入されました。これにより、CTE(WITH 句内のサブクエリ)が 1 回だけ評価され、一時テーブルに格納されるようになります。

UK 不動産価格データセット を使って、この句の使い方を見ていきましょう。次のクエリは、最も高価な不動産とともに、その郡でその年に販売された不動産の平均価格、および全期間での平均価格を返します。

WITH county_year_avg AS MATERIALIZED
    (
        SELECT county, toYear(date) AS year, avg(price) AS avg_price
        FROM uk_price_paid3
        GROUP BY county,year
    )
SELECT p.price, p.addr1, p.town,
    p.county,
    toYear(p.date) AS year,
    round(cya.avg_price) AS countyYear,
    round(ca.avg_price) AS countyAllTime
FROM uk_price_paid3 AS p
INNER JOIN county_year_avg AS cya 
ON (p.county = cya.county) AND (toYear(p.date) = cya.year)
INNER JOIN
(
    SELECT county, avg(avg_price) AS avg_price
    FROM county_year_avg
    GROUP BY county
) AS ca ON p.county = ca.county
ORDER BY p.price DESC
LIMIT 10;

CTE は、次の設定が構成されている場合にのみマテリアライズされます。

SET enable_materialized_cte=1;

このクエリの実行結果を以下に示します。

┌─────price─┬─street────────────┬─p.county───────┬─year─┬─ctyYear─┬─ctyAllTime─┐
│ 900000000 │ VICTORIA ROAD     │ KENT           │ 2021 │  457070 │     251980 │
│ 594300000 │ BAKER STREET      │ GREATER LONDON │ 2017 │  797029 │     466002 │
│ 569200000 │ STANHOPE ROW      │ GREATER LONDON │ 2018 │  821394 │     466002 │
│ 542540820 │ FORTESS ROAD      │ GREATER LONDON │ 2019 │  837867 │     466002 │
│ 523000000 │ NINE ELMS LANE    │ GREATER LONDON │ 2021 │  800579 │     466002 │
│ 494400000 │ NEWMARKET LANE    │ WEST YORKSHIRE │ 2019 │  244610 │     154516 │
│ 494400000 │ NEWMARKET LANE    │ WEST YORKSHIRE │ 2019 │  244610 │     154516 │
│ 480000000 │ SUTHERLAND AVENUE │ WEST MIDLANDS  │ 2022 │  343339 │     170087 │
│ 480000000 │ COOPER STREET     │ WEST MIDLANDS  │ 2022 │  343339 │     170087 │
│ 480000000 │ SUTHERLAND AVENUE │ WEST MIDLANDS  │ 2022 │  343339 │     170087 │
└───────────┴───────────────────┴────────────────┴──────┴─────────┴────────────┘

CTE をマテリアライズしない場合の実行時間は次のとおりです。

10 rows in set. Elapsed: 2.590 sec. Processed 91.36 million rows, 892.55 MB (35.27 million rows/s., 344.56 MB/s.)
Peak memory usage: 1.50 GiB.

10 rows in set. Elapsed: 2.707 sec. Processed 91.36 million rows, 892.55 MB (33.75 million rows/s., 329.71 MB/s.)
Peak memory usage: 1.50 GiB.

10 rows in set. Elapsed: 2.636 sec. Processed 91.36 million rows, 892.55 MB (34.66 million rows/s., 338.59 MB/s.)
Peak memory usage: 1.50 GiB.

マテリアライズした場合の実行時間は次のとおりです。

10 rows in set. Elapsed: 1.243 sec. Processed 60.91 million rows, 679.63 MB (49.02 million rows/s., 546.98 MB/s.)
Peak memory usage: 87.40 MiB.

10 rows in set. Elapsed: 1.219 sec. Processed 60.91 million rows, 679.63 MB (49.98 million rows/s., 557.68 MB/s.)
Peak memory usage: 88.97 MiB.

10 rows in set. Elapsed: 1.229 sec. Processed 60.91 million rows, 679.63 MB (49.58 million rows/s., 553.17 MB/s.)
Peak memory usage: 87.43 MiB.

マテリアライズしたバージョンは 2 倍強高速です。このデータセットは 3,000 万件とそれほど大きくないため、より大規模なデータではさらに大きな改善が見られます。

整形された EXPLAIN

コントリビューター: Kirill Kopnev

26.3 リリースでは、EXPLAIN 句の使用時に利用できる新しい設定も導入されました。

  • pretty=1 - ツリースタイルのインデント出力。
  • compact=1 - Expression ステップを折りたたむ。

前のセクションのクエリの先頭に次を追加するとします。

EXPLAIN indexes=1, pretty=1, compact=1

CTE をマテリアライズしない場合、次の出力が得られます。

2026-03-30_12-38-17.png

マテリアライズした場合は次の出力になります。

2026-03-30_12-38-05.png

自然順ソート

コントリビューター: Nazarii Piontko

naturalSortKey 関数により、人間にわかりやすい順序でのソートが可能になります。

たとえば、ClickHouse に地理空間関数がいつ追加されたかを調べたい場合、次のクエリを作成できます。

SELECT introduced_in, count()
FROM system.functions
WHERE categories LIKE '%Geo%'
GROUP BY ALL
ORDER BY introduced_in;
┌─introduced_in─┬─count()─┐
│ 1.1.0         │       5 │
│ 20.1.0        │      10 │
│ 20.3.0        │       6 │
│ 20.4.0        │       1 │
│ 21.11.0       │       4 │
│ 21.4.0        │      24 │
│ 21.9.0        │      11 │
│ 22.1.0        │       3 │
│ 22.2.0        │       5 │
│ 22.6.0        │      15 │
│ 25.10.0       │       4 │
│ 25.11.0       │       6 │
│ 25.12.0       │       1 │
│ 25.6.0        │       2 │
│ 25.7.0        │       2 │
└───────────────┴─────────┘

通常のソート順では、21.11.0 が 21.4.0 や 21.9.0 の前に来てしまい、期待どおりの結果になりません。この新しい関数を使用することで、期待どおりの順序でデータをソートできます。

SELECT introduced_in, count()
FROM system.functions
WHERE categories LIKE '%Geo%'
GROUP BY ALL
ORDER BY naturalSortKey(introduced_in);
┌─introduced_in─┬─count()─┐
│ 1.1.0         │       5 │
│ 20.1.0        │      10 │
│ 20.3.0        │       6 │
│ 20.4.0        │       1 │
│ 21.4.0        │      24 │
│ 21.9.0        │      11 │
│ 21.11.0       │       4 │
│ 22.1.0        │       3 │
│ 22.2.0        │       5 │
│ 22.6.0        │      15 │
│ 25.6.0        │       2 │
│ 25.7.0        │       2 │
│ 25.10.0       │       4 │
│ 25.11.0       │       6 │
│ 25.12.0       │       1 │
└───────────────┴─────────┘

JSONExtract の JSON 型対応

コントリビューター: Fisnik Kastrati

ClickHouse 26.3 より前は、以下の例に示すように、JSONExtract 関数 は JSON 文字列からフィールドを抽出することしかできませんでした。

WITH '{"ClickHouse":{"version":"26.3"}}' AS s
SELECT s, toTypeName(s), JSONExtractString(s, 'ClickHouse', 'version');
┌─s─────────────────────────────────┬─toTypeName(s)─┬─JSONExtractS⋯ 'version')─┐
│ {"ClickHouse":{"version":"26.3"}} │ String        │ 26.3                     │
└───────────────────────────────────┴───────────────┴──────────────────────────┘

この関数を使って JSON 型からフィールドを抽出しようとすると、次の例外が発生していました。

WITH '{"ClickHouse":{"version":"26.3"}}'::JSON AS s
SELECT s, toTypeName(s), JSONExtractString(s, 'ClickHouse', 'version');
Received exception:
Code: 43. DB::Exception: The first argument of function JSONExtractString should be a string containing JSON, illegal type: JSON: In scope WITH CAST('{"ClickHouse":{"version":"26.3"}}', 'JSON') AS s SELECT JSONExtractString(s, 'ClickHouse', 'version'). (ILLEGAL_TYPE_OF_ARGUMENT)

26.3 で同じクエリを実行すると、次の出力が返されます。

┌─s─────────────────────────────────┬─toTypeName(s)─┬─JSONExtractS⋯ 'version')─┐
│ {"ClickHouse":{"version":"26.3"}} │ JSON          │ 26.3                     │
└───────────────────────────────────┴───────────────┴──────────────────────────┘

WebAssembly UDF

コントリビューター: Vladimir Cherkasov, Alexey Smirnov, Vasily Chekalkin

26.3 から、WebAssembly によるユーザー定義関数 (UDF) を作成できるようになりました。WASM にコンパイルできる任意の言語で UDF を記述できます。これらの関数の実行は Wasmtime でサンドボックス化されます。

現時点では実験的機能であるため、サーバーレベルで有効にする必要があります。

config.d/webassembly.xml

<clickhouse>
   <allow_experimental_webassembly_udf>true</allow_experimental_webassembly_udf>
   <webassembly_udf_engine>wasmtime</webassembly_udf_engine>
</clickhouse>

設定が完了すると、次のクエリを実行して登録済みの WebAssembly UDF を確認できます。

SELECT * 
FROM system.webassembly_modules;
┌─name────┬─code─┬──────────────────────────────────────────────────────────────────────────hash─┐
│ collatz │      │ 72604391076586157580802760480449151909954051103190340835087306247242304166984 │ 
└─────────┴──────┴───────────────────────────────────────────────────────────────────────────────┘

この機能のステップごとの例については、WebAssembly User-Defined Functions ガイドを参照してください。

TTL DELETE 向けのバーティカルマージ

murphy-4o によるコントリビューション

ClickHouse では、INSERT ごとにテーブルのソートキーでソートされた新しいデータパートが作成されます。挿入の高速性を維持するため、追加のデータ処理はバックグラウンドでのパートマージへと後回しにされます。

これらのマージは継続的に実行され、小さなパートを結合してより大きなパートにまとめます。その過程で、ClickHouse はデータスキッピング向けにデータ配置を改善するだけでなく、行の置換、行の削除、行の更新、あるいはデータの事前集約といったメンテナンスタスクも実行します。

マージを効率的に実行するために、ClickHouse はテーブルの幅、行数、データサイズなどの要素に基づいて、2 つのマージアルゴリズムのいずれかを自動的に選択します。

1. ホリゾンタルマージ

  • 全カラムをまとめてブロック単位で読み込み、マージします

  • マージされたデータをディスクへ書き戻します

2. バーティカルマージ

  • まずソートキーのカラムのみを読み込んでマージします

  • 残りのカラム向けに最終的な行の並び順を一時的に記録します

  • その後、残りのカラムを 1 つずつ処理して書き込みます

違いをより明確に理解するために、各マージ戦略が実際にどのように機能するかを見てみましょう。

ホリゾンタルマージ: シンプルで CPU 効率が高い

ホリゾンタルマージはシンプルです。すべてのパートがすでに同一のキーでソートされているため、ClickHouse はマージソートと同様に、1 回の線形マージパスを実行します。

  • パートを順次読み込みます

  • その場で行を比較します

  • マージされた新しいパートを書き込みます

以下のアニメーションは、ソートキーが (town, street) であるテーブルのデータパートの例を使用して、この動作を示しています。

Loading video...

アニメーションは、水平マージ(horizontal merge)の処理プロセスを 3 つのステップで示しています。

① ブロックのマージ

複数のパートからデータがブロック単位で読み出され、ソートキーに基づいて 1 回の線形マージパスでメモリ上でマージされます。わかりやすくするため、アニメーションではブロック単位の処理ではなくパート全体として表現しています。

② 新しいパートへのブロックの書き出し

マージされたデータが新しいデータパートに書き出されます。ここでも簡略化のため、アニメーションでは単一のステップとして表現しています。

③ 古いパートの非アクティブ化

マージが完了すると、元のパートは非アクティブとしてマークされ、最終的に削除されます。

ワイドテーブル(例: 100 以上のカラムを持つテーブル)では、このアプローチはメモリ消費が大きくなる可能性があります。

マージは行ブロック単位で動作するため、ClickHouse はワイドな行のブロック全体をメモリにロードする必要があります。テーブルのカラム数が増えるほど、この処理の負荷は高くなります。

これに対処するため、ClickHouse は別のマージ戦略を採用しています。

垂直マージ: ワイドテーブル向けにメモリを最適化

垂直マージ(vertical merge)は、カラムを個別に処理することでメモリ使用量を削減します。

以下のアニメーションは、ソートキーが (town, street) であるテーブルでの動作を示しています。簡略化のため、追加のカラムは price のみを表示していますが、他のカラムも同様に処理されます。

Loading video...

アニメーションは、垂直マージのプロセスを 5 つのステップで示しています:

① まずソートキーのカラムをマージ

複数のパートからのデータがブロックごとに読み込まれ、ソートキーを使ってインメモリで単一のリニアパスによりマージされます。わかりやすくするため、アニメーションでは複数のカラムブロックではなくカラム全体として表示しています。

② 行の順序を記録し、キーカラムを書き込み

マージ後の最終的な行順序が一時的に保存され、マージされたソートキーのカラムが新しいデータパートに書き込まれます。

③ 記録された行順序に従って次のカラムをマージ

残りのカラムが1つずつ処理されます。カラムごとに、すべてのパートからブロック単位でデータが読み込まれ、事前に記録された最終的な行順序に従ってマージされます。アニメーションでは、これを1つのステップかつ1つのカラムのみとして表現しています。

このようにカラム単位かつブロック単位で処理を組み合わせることが、垂直マージのメモリ効率を高める要因です。

④ 新しいパートにカラムデータを追加

各カラムの処理が終わるごとに、マージされたカラムデータが新しいデータパートへ追記されます。

⑤ 古いパートを非アクティブ化

すべてのカラムの処理が完了すると、元のパートは非アクティブとしてマークされ、最終的に削除されます。

このマージ戦略は、すべてのカラムを一度にロードするとメモリ消費が大きくなるワイドテーブルに対して、より効率的です。

実際には、ClickHouseは効果が見込める場合にのみ垂直マージを使用します。

ClickHouseはどのような場合に垂直マージを使用するのか?

デフォルト設定では、マージ対象のパートの合計行数が131,072 行以上、または主キー以外のカラム数が11 カラム以上の場合に、垂直マージの対象となります。

言い換えれば、追加の管理オーバーヘッドを上回るメモリ削減効果が見込めるマージにおいて、ClickHouseはよりメモリ効率の高い垂直マージアルゴリズムへ自動的に切り替えます。

これは、時間の経過とともに大量のデータが蓄積され、ワイドテーブルに格納されることが多いTTLドリブンなワークロードにおいて、頻繁に当てはまります。

ワイドテーブル向けの高効率なTTL DELETE

ClickHouseでは、TTLルールを定義して、一定期間が経過したテーブルデータを自動的に削除できます。

これは、ログ、イベント、テレメトリストリーム、ローリング分析用データセットなど、時間の経過に伴って不要になるデータに特に有用です。

こうしたワークロードでは通常、時間とともに大量のデータが蓄積されます。また、現代のオブザーバビリティのユースケースでは、そうしたデータがワイドイベントとして保存され、1行に膨大な数の属性が含まれることもよくあります。

その結果、TTLベースの削除は大規模なワイドテーブルに対して実行されることが多く、マージ処理のメモリ消費が大きくなりやすくなります。

前述のとおり、TTL DELETEはバックグラウンドマージ中に実行されます。ただし、パート同士を結合するのではなく、個別のパートを読み込み、TTLルールでフィルタリングしたうえで再書き込みします。

バージョン26.3以降、TTL DELETE操作で垂直マージが使用可能になり、処理中のメモリ使用量が削減されます。

この動作は、新しいMergeTree設定であるvertical_merge_optimize_ttl_delete (デフォルトで有効)によって制御されます。

非同期挿入をデフォルトで有効化

コントリビューター: Sema Checherinda

前述の「TTL DELETE向けの垂直マージ」セクションで説明したように、ClickHouseは独立したデータパートを書き込み、後からバックグラウンドでマージすることで、高い挿入スループットを実現しています。

短い時間枠内で多数の小さなパートを作成してマージすることはリソース消費が大きいため、最適なパフォーマンスを得るには挿入をバッチ処理する必要があります。

バッチ処理はクライアント側で行うことも、ClickHouseの非同期挿入を使用することもできます。

非同期挿入は、データのバッチ処理をクライアント側からサーバー側へ移行します: INSERTクエリからのデータはまずバッファに挿入され、タイムアウト、蓄積データサイズ、または挿入回数をトリガーとする次のバッファフラッシュ時にストレージへ書き込まれます。

Screenshot 2026-04-06 at 15.02.48.png

非同期挿入に関する最初のブログ記事を公開して以来、さらなる改良と最適化を重ねてきました。

たとえば24.2以降、非同期挿入では挿入の頻度に基づいてバッファフラッシュのタイムアウトを自動調整する適応型アルゴリズムが採用されています。

バージョン26.1では、マテリアライズドビューを伴う非同期挿入向けの一貫した重複排除メカニズムを導入しました。

そして今回の26.3 LTS以降、非同期挿入がデフォルトで有効になりました。

ClickHouseは小さな挿入を自動的にバッチ処理し、頻繁な書き込みによって作成されるパート数を削減します。大半のユーザーは設定を変更する必要がありません。

ANTI、SEMI、FULL向けのJOIN順序の並べ替え

コントリビューター: Hechem Selmi

「JOINパフォーマンスの最適化はいつ終わるのですか?」決して終わりません!

進化を遂げたのは非同期挿入だけではありません。ここ数か月でJOIN順序の並べ替え (JOIN reordering) も大幅に改善されました (関連して、先月もRIGHT OUTER JOINとFULL OUTER JOINのパフォーマンスを改善したばかりです)。

JOIN順序の並べ替えの基礎知識

改めて整理すると、複数のテーブルを結合する場合、結合順序は結果の正しさには影響しませんが、パフォーマンスには極めて大きな影響を与えます。結合順序の違いによって生成される中間データの量が大幅に変わるためです。ClickHouseのデフォルトのハッシュベースの結合アルゴリズムは各結合の片側からインメモリ構造を構築するため、ビルド側の入力を小さく抑える結合順序を選択することが、高速かつ効率的な実行において極めて重要です。

ClickHouseにおけるJOIN順序並べ替えの進化

ClickHouseにおけるJOIN順序の並べ替えは、近年のリリースで大きく進化してきました:

  • まず、結合される2つのテーブルを対象としたローカルでの自動JOIN順序並べ替えが導入されました。これにより、オプティマイザは2つのうち小さい方のテーブルを右側 (ビルド側) へ配置できるようになり、ハッシュテーブルの構築に必要な処理負荷が軽減されました。(24.12)

  • 続いてグローバルでの自動JOIN順序並べ替えが登場し、数十のテーブルにまたがる複雑な結合グラフや、最も一般的な結合タイプ (INNER、OUTER、CROSS、SEMI、ANTI) にわたる効率的な最適化が可能になりました。(25.09)

これにより大幅な改善がもたらされ、たとえばあるTPC-Hのサンプルクエリでは、1,450 倍の高速化とメモリ使用量の 25 分の 1 への削減が達成されました。

  • 意思決定をさらに向上させるため、ClickHouseは自動カラム統計を導入し、結合順序に対するより優れたコスト見積もりを可能にしました。(25.10)

  • 最後に、INNER JOIN向けにより強力なJOIN順序並べ替えアルゴリズム (DPsize) が追加され、より広範な結合順序の探索空間を調べることで、多くの場合でより効率的な実行プランを生成できるようになりました。(25.12)

今回の進化: ClickHouseがサポートするすべての主要な結合タイプでのJOIN順序並べ替え

ClickHouseは、ANTI、SEMI、FULL結合を含む、**すべての主要な結合タイプ**で順序の並べ替えが可能になりました。

以前はINNERおよびLEFT/RIGHT結合に限定されていましたが、オプティマイザはすべての主要な結合タイプにわたって最も効率的なビルド側を自動的に選択し、より優れたプランの生成とメモリ使用量の削減を実現します。

これには、テーブルで統計情報が有効化されている必要があります。

Sharded Map

コントリビューター: Pavel Kruglov

本リリースでは、オブザーバビリティのワークロードに特に有用な最適化である「TTL DELETE向けの垂直マージ」が導入されただけでなく、ClickHouseのMapデータ型の内部ストレージも改善され、それらのワークロードで一般的なアクセスパターンが高速化されました。

オブザーバビリティワークロードにおけるMap

OpenTelemetry (OTEL) イベントなどのオブザーバビリティデータには、多くの場合多数のタグが含まれています。これらのタグは、記録された各イベントに追加のコンテキストを提供するシンプルなキー・バリューのペアです。

タグは本質的にフラットであるため、深くネストされた構造をサポートするJSONのようなデータ型の恩恵は受けません。

代わりに、キー・バリューペアのコレクションであるMapデータ型が、タグの構造に自然に適合します。

現在のMapの保存方法

内部的には、ClickHouseのMapはArray(Tuple(Key, Value))として扱われます。下の図は、Map型のtagsカラムを持つテーブルに挿入された2つの行が、ディスク上にどのように保存されるかを示しています。

Screenshot 2026-04-13 at 17.41.17.png

図が示すように、Mapカラムはディスク上では2つの独立した配列として保存されます: 1つはすべてのキーを含み、もう1つは対応する値を含みます。これらの配列はオフセットファイルと組み合わされ、各エントリが所属するテーブルの行へとマッピングされます。

課題

実際のクエリでは通常、マップ内の少数のキーのみにアクセスします。キーと値はインデックスなしのプレーンな配列として保存されているため、すべての検索において配列全体をスキャンする必要があり、不要なデータ読み込みが発生していました。

解決策

これに対処するため、新しいストレージ形式ではキーをハッシュベースのバケットにグループ化し、マップデータを複数のサブ配列に分割します。その結果、tags['status']のような単一のキーへのアクセスでは、カラム全体ではなく対応するバケットのみを読み込むだけで済みます。

これにより、一般的な検索パターンで処理されるデータ量が大幅に削減されます。

挿入への影響はなし

重要な点として、この最適化は挿入パフォーマンスに悪影響を与えません。新しいデータは既存のフォーマットで書き込まれ、バケット化されたレイアウトは後からのバックグラウンドマージ時に適用されます。

次の図は、Map型のtagsカラムを持つテーブルに対する2回の挿入について、この流れの概略を示しています。

Screenshot 2026-04-13 at 17.41.46.png

図は3つのステップを示しています:

① 挿入 → レベル0パート (デフォルト形式)

各挿入では、標準のMapレイアウトを使用して新しいデータパートが作成されます。キーと値はバケット化されず、2つのフラットな配列として保存されます。

② さらなる挿入 → 別のレベル0パート

2回目の挿入により、同じフォーマットで別のパートが生成されます。この段階では、すべてのマップデータは依然として完全なキーと値の配列として保存されています。

単一のキーへアクセスするには配列全体をスキャンする必要がありますが、レベル0パートは小さいため、通常これは問題になりません。

③ バックグラウンドマージ → バケット化されたMapストレージ

次回のバックグラウンドマージ時に、ClickHouseはキーをハッシュベースのバケットに分割してMapデータを再編成します。各バケットは、キーのサブセットとそれに対応する値をより小さな配列に格納します。

tags['status']のようなキーにアクセスする際、ClickHouseはキーのハッシュを使用して対応するバケット (例: bucket 3) を特定し、その配列のみを読み込むため、スキャンする必要があるデータ量が大幅に削減されます。

パフォーマンスへの影響

実際には、マップのサイズに応じて単一キーの検索が 2〜49 倍高速化されます。

設定

この動作は、with_bucketsに設定された新しいMergeTree設定であるmap_serialization_versionによって制御され、max_buckets_in_mapはデータを最大いくつのバケットに分割するかを指定します (デフォルトは32)。

追加の設定により、正確なレイアウトをさらに制御できます。上の図に示した例では、バケット化された構造は以下の設定によって実現されています:

  • map_serialization_version_for_zero_level_parts = 'basic'
  • map_serialization_version = 'with_buckets'
  • max_buckets_in_map = 3
  • map_buckets_strategy = 'const'
  • map_buckets_min_avg_size = 0

今すぐ始める

ClickHouse が自社データでどのように機能するかご興味はおありですか?ClickHouse Cloud はわずか数分で利用開始でき、300 ドル分の無料クレジットが付与されます。

サインアップ

この記事をシェア

  • Y Combinator icon
  • X icon
  • Bluesky icon
  • Facebook icon
  • LinkedIn icon

Subscribe to our newsletter

Stay informed on feature releases, product roadmap, support, and cloud offerings!

Follow us

XBlueskySlackGithubTelegramMeetupRSS