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

Кэш Условий Запроса

Многие реальные рабочие нагрузки включают повторяющиеся запросы к одним и тем же или почти тем же данным (например, ранее существующие данные плюс новые данные). 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, поскольку части являются неизменяемыми и создаются только с помощью 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 управляет тем, должен ли конкретный запрос или все запросы текущей сессии использовать кэш условий запроса.

Например, первое выполнение запроса

сохранит диапазоны таблицы, которые не соответствуют предикату. Последующие выполнения того же запроса, также с параметром 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.

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