クエリ条件キャッシュ は、デフォルト値である enable_analyzer が true に設定されている場合にのみ動作します。
WHERE col = 'xyz') を評価すれば、常に同じ結果になるという考え方に基づいています。
より具体的には、クエリ条件キャッシュ は、評価された各フィルタと各 グラニュール (= デフォルトでは 8192 行の block) について、その グラニュール 内にフィルタ条件を満たす行が 1 行もないかどうかを記憶します。
この情報は 1 ビットで記録されます。0 ビットはフィルタに一致する行がないことを表し、1 ビットは少なくとも 1 行は一致する行があることを意味します。
前者の場合、ClickHouse はフィルタの評価時に対応する グラニュール をスキップできます。後者の場合、その グラニュール は読み込んで評価する必要があります。
クエリ条件キャッシュ が効果を発揮するには、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 ビット (一致する行なし) で記録される グラニュール が増え、後続のフィルタ評価で「刈り込み」できるデータも増えます.
メモリ消費量
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 を指定すると、クエリ条件キャッシュを利用してスキャンするデータ量を減らせます。
ORDER BY ... LIMIT n (TopK) クエリ
ORDER BY <column> LIMIT n。動的フィルタリングまたはソートカラムの minmax スキップ索引によって高速化) を使用するクエリでも、クエリ条件キャッシュが使用されます。
TopK の読み取りでは、クエリの実行中に変化するしきい値に基づいてグラニュールをスキップできるため、cache エントリは TopK プランのパラメータおよび読み取られるパーツのセットごとにパーティション化されます。同じパーツに対して同じプランを持つクエリのみがそれらを再利用します。
このような読み取りは、設定 use_query_condition_cache_for_top_k (デフォルト: 有効) によりキャッシュから完全に除外できます。この設定は、use_query_condition_cache も有効な場合にのみ適用されます。
管理
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” に影響しません。