Перейти к основному содержанию
Перейти к основному содержанию

Кэш условий запроса

Примечание

Кэш условий запроса работает только, когда enable_analyzer установлен в значение true, что является значением по умолчанию.

Во многих реальных рабочих нагрузках выполняются повторяющиеся запросы к одним и тем же или почти тем же данным (например, к уже существующим данным плюс новым данным). ClickHouse предоставляет различные техники оптимизации для таких шаблонов запросов. Один из вариантов — настроить физическую организацию данных с помощью индексных структур (например, индексы первичного ключа, пропускающие индексы, проекции) или предварительных вычислений (материализованные представления). Другой вариант — использовать кэш запросов ClickHouse, чтобы избежать повторной обработки запросов. Недостаток первого подхода в том, что он требует ручного вмешательства и мониторинга со стороны администратора базы данных. Второй подход может возвращать устаревшие результаты (так как кэш запросов транзакционно не согласован), что может быть как приемлемо, так и неприемлемо в зависимости от сценария использования.

Кэш условий запроса предоставляет элегантное решение обеих этих проблем. Он основан на идее, что вычисление фильтра (например, WHERE col = 'xyz') над одними и теми же данными всегда возвращает один и тот же результат. Более конкретно, кэш условий запроса запоминает для каждого вычисленного фильтра и каждой гранулы (= блок 8192 строк по умолчанию), существует ли в грануле хотя бы одна строка, удовлетворяющая условию фильтра. Эта информация записывается в виде одного бита: бит 0 означает, что ни одна строка не подходит под фильтр, тогда как бит 1 означает, что существует как минимум одна подходящая строка. В первом случае ClickHouse может пропустить соответствующую гранулу при вычислении фильтра, во втором случае гранулу необходимо загрузить и обработать.

Кэш условий запроса эффективен, если выполняются три предпосылки:

  • Во‑первых, нагрузка должна многократно вычислять одни и те же условия фильтрации. Это естественным образом происходит, если один и тот же запрос выполняется несколько раз, но это также возможно, если два запроса используют одни и те же фильтры, например SELECT product FROM products WHERE quality > 3 и SELECT vendor, count() FROM products WHERE quality > 3.
  • Во‑вторых, большая часть данных должна быть неизменяемой, то есть не изменяться между запросами. В ClickHouse это обычно так, поскольку части (parts) неизменяемы и создаются только с помощью INSERT.
  • В‑третьих, фильтры должны быть селективными, то есть лишь относительно небольшое число строк удовлетворяет условию фильтра. Чем меньше строк соответствует условию фильтра, тем больше гранул будет записано с битом 0 (нет подходящих строк), и тем больше данных можно будет «отсечь» при последующих вычислениях фильтра.

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

Поскольку кэш условий запроса хранит только один бит на условие фильтрации и гранулу, он потребляет совсем немного памяти. Максимальный размер кэша условий запроса можно настроить с помощью серверного параметра query_condition_cache_size (по умолчанию: 100 МБ). Размер кэша 100 МБ соответствует 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 DROP QUERY CONDITION CACHE.

Содержимое кэша отображается в системной таблице system.query_condition_cache. Чтобы вычислить текущий размер кэша условий запросов в МБ, выполните SELECT formatReadableSize(sum(entry_size)) FROM system.query_condition_cache. Если требуется исследовать отдельные фильтрующие условия, проверьте поле condition в system.query_condition_cache. Обратите внимание, что это поле заполняется только в том случае, если запрос выполняется с включённой настройкой query_condition_cache_store_conditions_as_plaintext.

Количество попаданий и промахов кэша условий запросов с момента запуска базы данных отображается как события «QueryConditionCacheHits» и «QueryConditionCacheMisses» в системной таблице system.events. Оба счётчика обновляются только для запросов SELECT, которые выполняются с настройкой use_query_condition_cache = true, другие запросы не влияют на счётчик «QueryCacheMisses».