データスキップインデックスの例
このページでは、ClickHouse のデータスキップインデックスの例をまとめ、各インデックスの定義方法、使用すべきタイミング、適用されているかを検証する方法を示します。これらの機能はすべて MergeTree-family テーブル で動作します。
インデックス構文:
ClickHouse は 5 種類のスキップインデックスをサポートしています:
| Index Type | Description |
|---|---|
| minmax | 各グラニュール内の最小値と最大値を追跡する |
| set(N) | グラニュールごとに最大 N 個の異なる値を保持する |
| bloom_filter([false_positive_rate]) | 存在チェックのための確率的フィルタ |
| ngrambf_v1 | 部分文字列検索用の N-gram Bloom フィルタ |
| tokenbf_v1 | フルテキスト検索用のトークンベース Bloom フィルタ |
各セクションではサンプルデータを用いた例を示し、クエリ実行時にインデックスが利用されているかを確認する方法を説明します。
MinMax インデックス
minmax インデックスは、おおまかにソートされたデータや、ORDER BY と相関のあるカラムに対する範囲条件に最適です。
EXPLAIN とプルーニングを用いた具体例を参照してください。
Set インデックス
ローカル(ブロック単位)のカーディナリティが低い場合に set インデックスを使用します。各ブロック内に多数の異なる値が存在する場合には効果がありません。
作成/マテリアライズのワークフローと、その適用前後の効果は、基本的な操作ガイドで確認できます。
汎用 Bloom フィルター(スカラー)
bloom_filter インデックスは、「干し草の山から針を探すような」等価比較や IN によるメンバーシップ判定に適しています。偽陽性率(デフォルト 0.025)を指定するオプションのパラメータを受け取ります。
部分文字列検索用の N-gram Bloom フィルター (ngrambf_v1)
ngrambf_v1 インデックスは、文字列を N-gram に分割します。LIKE '%...%' クエリに対して有効です。String/FixedString/Map(mapKeys/mapValues 経由)をサポートし、サイズ、ハッシュ数、シードを調整できます。詳細については、N-gram Bloom filter のドキュメントを参照してください。
このガイドでは、実践的な例と、token と ngram のどちらをいつ使用するかについて解説しています。
パラメータ最適化ヘルパー:
4つの ngrambf_v1 パラメータ(n-gram サイズ、ビットマップサイズ、ハッシュ関数の数、シード)は、パフォーマンスとメモリ使用量に大きな影響を与えます。想定される n-gram の件数と許容する偽陽性率に基づいて、最適なビットマップサイズとハッシュ関数数を計算するために、これらの関数を使用してください。
チューニングに関する完全なガイダンスについては、パラメータのドキュメントを参照してください。
単語ベース検索用の Token Bloom フィルタ (tokenbf_v1)
tokenbf_v1 は、英数字以外の文字で区切られたトークンをインデックス化します。hasToken、LIKE による単語パターン、または = / IN 演算子と併用して使用することを推奨します。String/FixedString/Map 型をサポートします。
詳細については、Token Bloom フィルタ ページおよび Bloom フィルタの種類 ページを参照してください。
トークンと ngram に関するオブザーバビリティの例とガイダンスについては、こちらを参照してください。
CREATE TABLE 時にインデックスを追加する(複数の例)
スキップインデックスは、複合式や Map / Tuple / Nested 型もサポートします。これは以下の例で示します。
既存データのマテリアライズと検証
MATERIALIZE を使って既存のデータパーツにインデックスを追加し、以下のように EXPLAIN やトレースログでプルーニングの動作を確認できます。
この具体的な minmax の例は、EXPLAIN 出力の構造とプルーニング件数を示しています。
スキップインデックスを使用すべき場合と避けるべき場合
スキップインデックスを使用すべき場合:
- フィルター対象の値がデータブロック内で疎に分布している場合
ORDER BY列との相関が強い、またはデータのインジェストパターンによって類似した値がまとまって格納されている場合- 大規模なログデータセットに対してテキスト検索を行う場合(
ngrambf_v1/tokenbf_v1型)
スキップインデックスを避けるべき場合:
- ほとんどのブロックに少なくとも 1 つは一致する値が含まれる可能性が高い場合(いずれにせよブロック全体が読み取られる)
- データの並び順と相関のない高カーディナリティ列でフィルタリングする場合
ある値がデータブロック内に一度でも出現すると、そのブロック全体を ClickHouse は読み取る必要があります。実運用に近いデータセットでインデックスを検証し、実際のパフォーマンス計測に基づいて粒度や型固有のパラメータを調整してください。
一時的にインデックスを無視または強制する
テストやトラブルシューティングの際に、個々のクエリごとに名前を指定して特定のインデックスを無効化できます。必要に応じてインデックスの使用を強制するための設定もあります。ignore_data_skipping_indices を参照してください。
注意事項と留意点
- スキップインデックスは MergeTree ファミリーのテーブル でのみサポートされます。プルーニングはグラニュール/ブロックレベルで行われます。
- Bloom filter ベースのインデックスは確率的な仕組みです(誤検出により余分な読み取りが発生しますが、有効なデータを取り逃がすことはありません)。
- Bloom filter およびその他のスキップインデックスは
EXPLAINとトレースで検証し、プルーニング効果とインデックスサイズのバランスが取れるように粒度を調整してください。