Condition Cache
Кратко Apache Doris Condition Cache сохраняет результат вычисления условия
WHEREдля каждого сегмента в виде сжатого битового вектора с ключом(predicate digest, key range). Следующий запрос, применяющий тот же фильтр к тому же сегменту, пропускает гранулы, для которых битовый вектор уже указывает на отсутствие совпадений, даже если список SELECT, GROUP BY или агрегация отличаются. Пять панелей дашборда с общим условиемWHERE region = 'ASIA' AND order_date >= '2023-01-01'вычисляют этот фильтр один раз для каждого сегмента и повторно используют результат во всех панелях.

Зачем использовать Apache Doris Condition Cache?
Apache Doris Condition Cache повторно использует результаты вычисления предикатов в запросах с одинаковым условием WHERE, которые во всём остальном могут различаться, заполняя пробел между SQL Cache и Query Cache. В большинстве аналитических нагрузок объём работы по фильтрации гораздо больше, чем по агрегации. Дашборд на основе одной таблицы orders может содержать десять панелей, у которых общее условие WHERE region = ? AND order_date >= ?, а различается только список SELECT. Бэкенд приложения каждые несколько секунд повторяет тот же предикат с новой агрегацией. Отчёт T+1 выполняет разные агрегации по партициям, которые не менялись с прошлой ночи.
В каждом из этих запросов кластер заново выполняет всю работу по вычислению предиката: читает столбец, декодирует его, выполняет сравнение, строит маску строк и затем переходит к остальной части плана.
SQL Cache помогает, когда текст SQL совпадает побайтно, и перестаёт работать при малейшем изменении списка SELECT. Query Cache помогает запросам агрегации, которые используют одни и те же tablet целиком. Ни один из них не помогает, когда условие WHERE общее, а список SELECT различается.
Apache Doris Condition Cache занимает место между ними: он кеширует этап вычисления предиката на уровне сегмента независимо от того, что остальная часть запроса делает со строками.
Что такое Apache Doris Condition Cache?
Apache Doris Condition Cache представляет собой кеш результатов вычисления предикатов на стороне BE. Для каждого сегмента результаты хранятся в виде битового вектора с детализацией до гранулы. При запуске сканирования сегмента BE вычисляет 64-битный дайджест на основе выражения предиката и диапазона ключей сегмента, затем проверяет кеш. При попадании он пропускает все гранулы с битом 0 и сканирует только гранулы с битом 1. При промахе он вычисляет предикат обычным образом и записывает полученный битовый вектор в кеш.
Кеш не зависит от проекций, агрегаций, соединений и сортировки. Два запроса с одинаковыми условиями WHERE используют общие записи кеша, даже если один выполняет SELECT *, а другой выполняет SELECT COUNT(DISTINCT customer_id).
Основные термины
enable_condition_cache: переменная сеанса. Включена по умолчанию; задайтеfalse, чтобы отключить кеш для одного запроса или одного сеанса.- Сегмент: файл внутри tablet, запись в который уже завершена. После записи сегмент больше не изменяется; вместо этого compaction создаёт новые сегменты. Эта неизменяемость и делает использование кеша безопасным.
- Гранула: блок из 2048 строк внутри сегмента. Битовые векторы хранят один бит на гранулу, а не на строку.
- Дайджест предиката: 64-битный хеш конъюнктивного предиката вместе с диапазоном ключей сегмента. Семантически эквивалентные предикаты дают одинаковый дайджест.
condition_cache_limit: ограничение объёма памяти для кеша на каждом BE, в MB. Значение по умолчанию:1024. Задаётся вbe.conf.
Как работает Apache Doris Condition Cache?
Apache Doris Condition Cache хеширует каждый конъюнктивный предикат вместе с диапазоном ключей сегмента в 64-битный дайджест, ищет его в локальном LRU-кеше BE и пропускает все гранулы, для которых сохранён бит 0.
- Вычисление дайджеста (BE). Когда оператор сканирования начинает работу с сегментом, он нормализует свои конъюнктивные предикаты и диапазон ключей сегмента, формируя 64-битный дайджест. Разные списки SELECT, условия GROUP BY и агрегации дают одинаковый дайджест, поскольку не влияют на предикат.
- Проверка для каждого сегмента. BE ищет
(digest, segment_id)в шардированном LRU-кеше. Если у сегмента есть маркер удаления или предикат сформирован runtime-фильтром TopN во время выполнения, BE пропускает поиск в кеше и выполняет обычное сканирование. - При попадании. Оператор сканирования читает битовый вектор, пропускает все гранулы с битом
0и декодирует столбцы только для гранул с битом1. Фильтрация на уровне строк в этих гранулах подтверждает совпадения. - При промахе. Оператор сканирования вычисляет предикат обычным образом, по ходу работы строит битовый вектор и записывает результат в кеш с ключом
(digest, segment_id). Последующие запросы с тем же дайджестом получают попадание в кеш. - Инвалидация благодаря неизменяемости. Сегменты не изменяются. Новая операция INSERT или compaction создаёт новый сегмент с новым ID, а старая запись кеша со временем самостоятельно вытесняется из LRU. Apache Doris не требуется отдельный этап инвалидации.
Быстрый старт
SET enable_condition_cache = true;
-- Run 1: misses every segment, builds bit vectors, writes them back
SELECT region, country, SUM(amount)
FROM orders
WHERE region = 'ASIA' AND order_date >= '2023-01-01'
GROUP BY region, country;
-- Run 2: different SELECT, same WHERE; hits the cache on every segment
SELECT COUNT(DISTINCT customer_id)
FROM orders
WHERE region = 'ASIA' AND order_date >= '2023-01-01';
Ожидаемый результат (фрагмент EXPLAIN PROFILE для запуска 2)
ConditionCacheSegmentHit: 42
ConditionCacheFilteredRows: 18,400,219
Первый запуск сканирует каждый сегмент, вычисляет предикат и записывает по одному битовому вектору на сегмент. Второй запуск использует то же условие WHERE, поэтому дайджест совпадает; для каждого сегмента происходит попадание в кеш, и BE пропускает гранулы, для которых уже известно, что они не содержат строк, соответствующих условию region = 'ASIA' AND order_date >= '2023-01-01'.
Когда стоит использовать Apache Doris Condition Cache?
Включайте Apache Doris Condition Cache для нагрузок с преобладанием чтения, где многие запросы повторно используют одно и то же условие WHERE, а таблица не испытывает постоянной высокой нагрузки на запись.
Подходящие сценарии
- Дашборды, где многие панели используют общее условие
WHEREи различаются только списком SELECT или агрегацией. - Трафик приложений, которые часто повторяют один и тот же предикат для таблиц с редкими операциями записи.
- Отчёты T+1, выполняющие разные агрегации по уже загруженным партициям за вчерашний день.
- Высокоселективные фильтры, при которых большинство гранул получают бит
0, а кеш позволяет пропускать большие части каждого сегмента при сканировании.
Неподходящие сценарии
- Таблицы с постоянной высокой нагрузкой на запись. Новые сегменты означают новые дайджесты, а старые записи кеша вытесняются из LRU раньше, чем используются повторно. Если нужно повторно использовать результаты агрегаций при неизменной структуре запроса, используйте Query Cache.
- Запросы, обращающиеся к сегментам с маркерами удаления. BE обходит кеш, чтобы сохранить корректную семантику удаления, поэтому при частых операциях
DELETEкеш срабатывает редко. - Запросы, предикат которых формируется runtime-фильтром TopN во время выполнения. Пока не поддерживаются.
- Низкоселективные фильтры, которым соответствует большинство строк. Затраты на сканирование подходящих гранул сохраняются; кеш экономит работу только на гранулах, для которых уже известно об отсутствии совпадений.
- Ситуативные запросы с разовыми условиями WHERE, которые не используются повторно в других запросах. Кеш заполняется записями, которые читаются по одному разу, а затем вытесняют друг друга. Можно оставить его включённым, но доля попаданий, скорее всего, будет низкой.
- Поиск по первичному ключу. Вместо этого используйте точечные запросы при высокой конкурентной нагрузке.
Дополнительные материалы
- Руководство пользователя Condition Cache
- Query Cache: кеш частичных агрегаций на уровне pipeline
- SQL Cache: кеш результатов для побайтно идентичного SQL
- Кеширование в Doris: выбор подходящей стратегии
- Data Cache и Page Cache: кеши уровня хранения, расположенные ниже Condition Cache и хранящие сами байты и декодированные страницы.
- Metadata Cache: кеш метаданных внешнего Catalog, дополняющий кеши данных.
- Архитектура MPP: модель выполнения, в план которой встраивается Condition Cache, чтобы пропускать повторное вычисление уже обработанных предикатов.