| --- |
| { |
| "title": "コンディションキャッシュ", |
| "language": "ja", |
| "description": "大規模な分析ワークロードでは、クエリに繰り返しフィルタリング条件(Conditions)が含まれることが多い" |
| } |
| --- |
| # Condition Cache |
| |
| ## はじめに |
| |
| 大規模な分析ワークロードでは、クエリにはしばしば**繰り返されるフィルタリング条件(Conditions)**が含まれます。例えば: |
| |
| ``` |
| SELECT * FROM orders WHERE region = 'ASIA'; |
| SELECT count(*) FROM orders WHERE region = 'ASIA'; |
| ``` |
| このようなクエリは、同一のデータセグメントに対して同じフィルタリングロジックを繰り返し実行するため、**冗長なCPUとI/Oオーバーヘッド**を引き起こします。 |
| |
| これに対処するため、**Apache DorisはCondition Cacheメカニズムを導入しています**。 |
| これは、特定の条件による指定されたセグメントでのフィルタリング結果をキャッシュし、後続のクエリが**それらの結果を直接再利用**できるようにすることで、**不要なスキャンとフィルタリング操作を削減**し、クエリレイテンシを大幅に低減します。 |
| |
| ## 動作原理 |
| |
| Condition Cacheの中核概念は以下の通りです: |
| |
| - **同一のフィルタリング条件は、同一のデータセグメントで同じ結果を生成する。** |
| - Dorisは「条件式 + キー範囲」の組み合わせから**64ビットダイジェスト**を生成し、これが一意のキャッシュ識別子として機能します。 |
| - 各セグメントは、このダイジェストを使用してキャッシュ内の既存のフィルタリング結果を検索できます。 |
| |
| キャッシュされた結果は、圧縮された**ビットベクトル(`std::vector<bool>`)**として格納されます: |
| |
| - **0**は行範囲が条件を満たさないことを示し、直接スキップできます; |
| - **1**は範囲に一致するデータが含まれている可能性があり、さらなるスキャンが必要であることを示します。 |
| |
| このメカニズムにより、Dorisは粗い粒度で無関係なデータブロックを迅速に除去し、必要な場合にのみ細かい粒度のフィルタリングを実行できます。 |
| |
| ## 適用可能なシナリオ |
| |
| Condition Cacheは以下の場合に最も効果的です: |
| |
| - **繰り返し条件**: 同一または類似のフィルタ条件が頻繁に使用される。 |
| - **比較的安定したデータ**: セグメント内のデータは通常不変(INSERT/Compaction後に新しいセグメントが生成され、古いキャッシュは自然に無効化される)。 |
| - **高い選択性**: フィルタが少数の行のサブセットのみを残す場合、スキャンの削減を最大化します。 |
| |
| Condition Cacheは以下の状況では**使用されません**: |
| |
| - **delete predicates**を含むクエリ(正確性を確保するため、キャッシュが無効化される)。 |
| - 実行時に生成される**TopN runtime filters**(現在サポートされていない)。 |
| |
| ## 設定と管理 |
| |
| ### 有効化または無効化 |
| |
| ``` |
| SET enable_condition_cache = true; |
| ``` |
| ### メモリ管理 |
| |
| - Condition Cacheはキャッシュ削除に**LRUポリシー**を使用します。 |
| - `condition_cache_limit`を超過した場合、最も使用頻度の低いエントリが自動的にクリアされます。 |
| |
| `be.conf`でメモリ制限を変更できます: |
| |
| ``` |
| condition_cache_limit = 1024 # Unit: MB |
| ``` |
| - セグメント圧縮後、古いキャッシュエントリは LRU エビクションにより自然に無効化されます。 |
| |
| ## キャッシュ統計 |
| |
| Doris は Condition Cache の効果をユーザーが監視するための包括的なメトリクスを提供しています: |
| |
| - **Profile レベルのメトリクス**(クエリ実行プランで表示) |
| - `ConditionCacheSegmentHit`: キャッシュにヒットしたセグメント数 |
| - `ConditionCacheFilteredRows`: キャッシュされた結果により直接スキップされた行数 |
| - **システムメトリクス**(監視システムまたは `/metrics` で表示可能) |
| - `condition_cache_search_count`: キャッシュルックアップの総数 |
| - `condition_cache_hit_count`: キャッシュヒットの成功数 |
| |
| これらのメトリクスはキャッシュの効果とヒット率の評価に役立ちます。 |
| |
| ## 使用例 |
| |
| ### 典型的なシナリオ |
| |
| 次のクエリを考えてみます: |
| |
| ``` |
| SELECT order_id, amount |
| FROM orders |
| WHERE region = 'ASIA' AND order_date >= '2023-01-01'; |
| ``` |
| - **初回実行**: クエリはフルスキャンを実行してフィルタを評価し、Condition CacheはLRUキャッシュに結果を保存します。 |
| - **後続の同一クエリ**: キャッシュされた結果を再利用し、無関係な行範囲の大部分をスキップして、潜在的な一致のみをスキャンします。 |
| |
| 複数のクエリが同じフィルタ条件を共有する場合(例:`region = 'ASIA' AND order_date >= '2023-01-01'`)、お互いのCondition Cacheエントリを再利用でき、全体的なワークロードを削減します。 |
| |
| ## 注意事項 |
| |
| - **キャッシュは永続的ではありません**: Condition CacheはDorisの再起動時にクリアされます。 |
| - **削除操作はキャッシングを無効にします**: 削除マーカーを持つセグメントは厳密な整合性が必要なため、キャッシュを使用しません。 |
| |
| ## まとめ |
| |
| Condition CacheはDorisにおける**反復的な条件クエリ**向けに設計された最適化メカニズムです。その利点は以下の通りです: |
| |
| - 冗長な計算を回避し、CPU/I/Oオーバーヘッドを削減 |
| - ユーザーの介入なしに自動的かつ透過的に効果を発揮 |
| - メモリ消費量が軽量で、ヒット率とフィルタ率が高い場合に非常に効率的 |
| |
| Condition Cacheを効果的に活用することで、ユーザーは高頻度なOLAPクエリシナリオにおいて大幅に高速な応答時間を実現できます。 |