主キーインデックス
このページでは、ClickHouseのスパース主インデックスの構築方法、動作原理、クエリの高速化にどのように役立つかを紹介します。
高度なインデックス戦略とさらに深い技術的詳細については、主インデックスの深掘りをご覧ください。
ClickHouseにおけるスパース主インデックスはどのように機能するのか?
ClickHouseのスパース主インデックスは、クエリの条件に一致するデータを含む可能性のあるグラニュール—行のブロック—を効率的に特定するのに役立ちます。次のセクションでは、このインデックスがそれらのカラムの値からどのように構築されるかを説明します。
スパース主インデックスの作成
スパース主インデックスがどのように構築されるかを示すために、uk_price_paid_simpleテーブルをいくつかのアニメーションとともに使用します。
リマインダーとして、①例示のテーブルには(^^主キー^^(town, street)があり、②挿入されたデータは③ディスクに保存され、^^主キー^^カラムの値に基づいてソートされ、圧縮された状態で、それぞれのカラム用の別々のファイルに格納されます:

処理のために、各カラムのデータは④論理的にグラニュールに分割されます—それぞれが8,192行をカバーします—これはClickHouseのデータ処理メカニズムが操作する最小単位です。
この^^グラニュール^^構造は主インデックスをスパースにする要因でもあります:すべての行をインデックス化するのではなく、ClickHouseは⑤各^^グラニュール^^から1行分の^^主キー^^値、具体的には最初の行の値だけを保存します。これにより、各^^グラニュール^^ごとに1つのインデックスエントリが生成されます:

スパース性のおかげで、主インデックスはメモリに完全に収まるのに十分小さく、^^主キー^^カラムに対する条件を持つクエリのフィルタリングを迅速に行うことを可能にします。次のセクションでは、これがどのようにそのようなクエリの加速に役立つかを示します。
主インデックスの使用
スパース主インデックスがクエリ加速にどのように使用されるか、別のアニメーションを用いて概説します:

①例示のクエリには、両方の^^主キー^^カラムに対する述語が含まれています: town = 'LONDON' AND street = 'OXFORD STREET'
。
②クエリを加速するために、ClickHouseはテーブルの主インデックスをメモリにロードします。
③その後、インデックスエントリをスキャンして、述語に一致する行を含む可能性のあるグラニュールを特定します—言い換えれば、スキップできないグラニュールです。
④これらの潜在的に関連するグラニュールがメモリにロードされ、クエリに必要な他のカラムの対応するグラニュールとともに処理されます。
主インデックスの監視
テーブル内の各data partには、それぞれの主インデックスがあります。これらのインデックスの内容をmergeTreeIndexテーブル関数を使用して調査できます。
以下のクエリでは、例示のテーブルの各データ^^part^^の主インデックスにおけるエントリの数を一覧表示します:
このクエリは、現在のデータ^^parts^^のうち1つの主インデックスからの最初の10エントリを示しています。これらの^^parts^^は、バックグラウンドで継続的にマージされて、より大きな^^parts^^となります:
最後に、EXPLAIN句を使用して、すべてのデータ^^parts^^の主インデックスが、例示のクエリの述語に一致する行を含むことができないグラニュールをスキップする方法を確認します。これらのグラニュールは、ロードおよび処理から除外されます:
EXPLAIN出力の行13には、すべてのデータ^^parts^^の中で、主インデックス分析によって処理のために選択されたグラニュールが3,609のうちのわずか3つであることが示されています。残りのグラニュールは完全にスキップされました。
また、クエリを実行するだけで、ほとんどのデータがスキップされたことも観察できます:
上記のように、例示のテーブル内の約3000万行のうち、約25,000行しか処理されませんでした:
主なポイント
-
スパース主インデックスは、ClickHouseが^^主キー^^カラムのクエリ条件に一致する行を含むグラニュールを特定することで、不必要なデータをスキップするのに役立ちます。
-
各インデックスは、各^^グラニュール^^の最初の行からの^^主キー^^値のみを保存しており(デフォルトでは^^グラニュール^^は8,192行です)、メモリに収まるコンパクトな構造となっています。
-
^^MergeTree^^テーブル内の各データ部分は、独立してクエリ実行時に使用される独自の主インデックスを持っています。
-
クエリ中、インデックスによりClickHouseはグラニュールをスキップすることができ、I/Oやメモリ使用量を削減しながらパフォーマンスを向上させます。
-
mergeTreeIndex
テーブル関数を使用してインデックスの内容を調査し、EXPLAIN
句でインデックスの使用状況を監視できます。
さらなる情報の入手先
ClickHouseにおけるスパース主インデックスの機能の詳細な説明や、従来のデータベースインデックスとの差異、使用に関するベストプラクティスについては、詳細なインデクシングの深掘りをご覧ください。
ClickHouseが主インデックススキャンで選択したデータをどのように高い並列性を持って処理するかに興味がある方は、クエリの並列性ガイドをこちらでご覧ください。