Перейти к основному содержанию
Кэш условий запроса работает только при значении true для enable_analyzer, которое используется по умолчанию.
Во многих реальных рабочих нагрузках одни и те же или почти одни и те же данные запрашиваются повторно (например, уже существующие данные плюс новые данные). ClickHouse предоставляет различные методы оптимизации для таких шаблонов запросов. Один из вариантов — настроить физическую структуру данных с помощью индексных структур (например, индексов первичного ключа, индексов пропуска данных, проекций) или предварительных вычислений (materialized views). Другой вариант — использовать кэш запросов ClickHouse, чтобы избежать повторного выполнения запроса. Недостаток первого подхода в том, что он требует ручного вмешательства и контроля со стороны администратора базы данных. Второй подход может возвращать устаревшие результаты (поскольку кэш запросов не является транзакционно согласованным), что в зависимости от сценария использования может быть как приемлемым, так и неприемлемым. Кэш условий запроса элегантно решает обе эти проблемы. Он основан на идее, что вычисление условия фильтрации (например, WHERE col = 'xyz') на одних и тех же данных всегда дает один и тот же результат. Точнее, кэш условий запроса запоминает для каждого вычисленного фильтра и каждой гранулы (= блока из 8192 строк по умолчанию), есть ли в грануле строки, удовлетворяющие условию фильтрации. Эта информация записывается в виде одного бита: бит 0 означает, что ни одна строка не соответствует фильтру, а бит 1 — что существует хотя бы одна подходящая строка. В первом случае ClickHouse может пропустить соответствующую гранулу при вычислении фильтра, во втором гранулу необходимо загрузить и проверить. Кэш условий запроса эффективен, если выполняются три обязательных условия:
  • Во-первых, рабочая нагрузка должна многократно вычислять одни и те же условия фильтрации. Это естественным образом происходит, если запрос повторяется несколько раз, но также возможно, если два запроса используют одни и те же фильтры, например SELECT product FROM products WHERE quality > 3 и SELECT vendor, count() FROM products WHERE quality > 3.
  • Во-вторых, большая часть данных должна быть неизменяемой, то есть не меняться между запросами. В ClickHouse это обычно так, поскольку части неизменяемы и создаются только операциями INSERT.
  • В-третьих, фильтры должны быть селективными, то есть условию фильтрации должно удовлетворять сравнительно небольшое число строк. Чем меньше строк соответствует условию фильтрации, тем больше гранул будет записано с битом 0 (нет подходящих строк), и тем больше данных можно будет “отсечь” при последующих вычислениях фильтра.

Потребление памяти

Поскольку кэш условий запроса хранит только один бит для каждой комбинации условия фильтрации и гранулы, он потребляет очень мало памяти. Максимальный размер кэша условий запроса можно настроить с помощью настройки сервера query_condition_cache_size (по умолчанию: 100 MB). Размер кэша в 100 MB соответствует 100 * 1024 * 1024 * 8 = 838,860,800 записей. Поскольку каждая запись представляет метку (по умолчанию 8192 строк), кэш может охватывать до 6,871,947,673,600 (6,8 триллиона) строк одного столбца. На практике фильтры вычисляются более чем по одному столбцу, поэтому это число нужно разделить на количество столбцов, по которым выполняется фильтрация.

Настройки конфигурации и использование

Параметр use_query_condition_cache определяет, должен ли конкретный запрос или все запросы в текущем сеансе использовать кэш условий запроса. Например, при первом выполнении запроса
SELECT col1, col2
FROM table
WHERE col1 = 'x'
SETTINGS use_query_condition_cache = true;
будет хранить диапазоны таблицы, которые не удовлетворяют предикату. При последующих выполнениях того же запроса, также с параметром use_query_condition_cache = true, будет использоваться кэш условий запроса, чтобы сканировать меньше данных.

Администрирование

Кэш условий запроса не сохраняется после перезапуска ClickHouse. Чтобы очистить кэш условий запроса, выполните SYSTEM CLEAR QUERY CONDITION CACHE. Содержимое кэша отображается в системной таблице system.query_condition_cache. Чтобы рассчитать текущий размер кэша условий запроса в МБ, выполните SELECT formatReadableSize(sum(entry_size)) FROM system.query_condition_cache. Если вы хотите изучить отдельные условия фильтрации, можете посмотреть поле condition в system.query_condition_cache. Обратите внимание: это поле доступно только в отладочных сборках. Количество попаданий и промахов кэша условий запроса с момента запуска базы данных отображается как события “QueryConditionCacheHits” и “QueryConditionCacheMisses” в системной таблице system.events. Оба счётчика обновляются только для SELECT-запросов, выполняемых с настройкой use_query_condition_cache = true; другие запросы не влияют на “QueryCacheMisses”.
Последнее изменение 10 июня 2026 г.