クエリ条件キャッシュ は、デフォルト値である enable_analyzer が true に設定されている場合にのみ動作します。
WHERE col = 'xyz') を評価すれば、常に同じ結果になるという考え方に基づいています。
より具体的には、クエリ条件キャッシュ は、評価された各フィルタと各 granule (= デフォルトでは 8192 行の block) について、その granule 内にフィルタ条件を満たす行が 1 行もないかどうかを記憶します。
この情報は 1 ビットで記録されます。0 ビットはフィルタに一致する行がないことを表し、1 ビットは少なくとも 1 行は一致する行があることを意味します。
前者の場合、ClickHouse はフィルタの評価時に対応する granule をスキップできます。後者の場合、その granule は読み込んで評価する必要があります。
クエリ条件キャッシュ が効果を発揮するには、3 つの prerequisites が満たされている必要があります。
- 第 1 に、workload が同じフィルタ条件を繰り返し評価する必要があります。これは同じクエリが複数回実行される場合には自然に起こりますが、2 つのクエリが同じフィルタを共有している場合にも起こりえます。たとえば
SELECT product FROM products WHERE quality > 3とSELECT vendor, count() FROM products WHERE quality > 3のような場合です。 - 第 2 に、データの大部分が不変である必要があります。つまり、クエリ間で変更されないということです。これは ClickHouse では一般的に当てはまります。parts は不変であり、INSERT によってのみ作成されるためです。
- 第 3 に、フィルタは選択性が高くなければなりません。つまり、フィルタ条件を満たす行が比較的少ないということです。フィルタ条件に一致する行が少ないほど、0 ビット (一致する行なし) で記録される granules が増え、後続のフィルタ評価で「刈り込み」できるデータも増えます.
メモリ消費量
query_condition_cache_size で設定できます (デフォルト: 100 MB) 。
キャッシュサイズ 100 MB は、100 * 1024 * 1024 * 8 = 838,860,800 エントリに相当します。
各エントリは 1 つのマーク (デフォルトでは 8192 行) を表すため、このキャッシュは単一のカラムの最大 6,871,947,673,600 (6.8 兆) 行をカバーできます。
実際には、フィルタは複数のカラムに対して評価されるため、この数はフィルタ対象のカラム数で割る必要があります。
設定と使用方法
use_query_condition_cache = true を指定すると、クエリ条件キャッシュを利用してスキャンするデータ量を減らせます。
管理
SYSTEM CLEAR QUERY CONDITION CACHE を実行します。
キャッシュの内容は、システムテーブル system.query_condition_cache に表示されます。
現在のクエリ条件キャッシュのサイズを MB 単位で計算するには、SELECT formatReadableSize(sum(entry_size)) FROM system.query_condition_cache を実行します。
個々のフィルタ条件を調査したい場合は、system.query_condition_cache のフィールド condition を確認できます。なお、このフィールドはデバッグビルドでのみ使用できます。
データベースの起動以降のクエリ条件キャッシュのヒット数とミス数は、システムテーブル system.events に “QueryConditionCacheHits” および “QueryConditionCacheMisses” というイベントとして表示されます。
これらのカウンターは、設定 use_query_condition_cache = true を指定して実行された SELECT クエリに対してのみ更新され、その他のクエリは “QueryCacheMisses” に影響しません。