deшка
Урок 10.12

Materialized views: инкрементальная и периодическая обработка

Что запускает представление, где лежит результат и почему изменения источника не пересчитывают историю.

Materialized view сохраняет результат вычисления для последующего чтения. Обычная VIEW хранит запрос и выполняет его при обращении. В ClickHouse есть два режима materialized view: обработка вставляемых блоков и периодический пересчёт запроса.

Инкрементальная view

Incremental materialized view выполняет SELECT над очередным вставленным блоком источника и записывает результат в целевую таблицу. Она переносит часть работы со времени чтения на время загрузки.

Пусть events хранит event_time и event_type, а daily_events принимает day, event_type и total. Счётчик можно описать так:

CREATE MATERIALIZED VIEW daily_events_insert
TO daily_events AS
SELECT
    toDate(event_time) AS day,
    event_type,
    count() AS total
FROM events
GROUP BY day, event_type;

TO обозначает уже существующую target-таблицу. Если она использует SummingMergeTree с ключом (day, event_type), то сохраняет и объединяет частичные счётчики. На чтении нужен sum(total) с GROUP BY: фоновые merges могли ещё не завершиться.

Первый блок с тремя click и второй с двумя дадут отдельные вклады 3 и 2; запрос объединит их в 5. Для средних передают сумму и количество или состояние агрегата.

Что запускает вычисление

Триггер — вставка в исходную таблицу. Merge, mutation, DELETE и TTL источника не запускают пересчёт ранее записанного результата. Замена старых версий в ReplacingMergeTree тоже не отменяет уже учтённые вклады.

Если SELECT view содержит JOIN со справочником, вставка в основной источник может использовать справочник. Изменение правой таблицы само по себе не пересчитывает витрину. Нужно определить, хранится атрибут на момент события или ожидается его актуальное значение.

Цепочка views увеличивает работу и число точек ошибки при INSERT. Обработку ошибок и повторов проверяют для каждой целевой таблицы: частично выполненная цепочка может оставить результаты только в части из них.

Существующая история

Создание incremental view не загружает старые строки автоматически. Backfill — отдельная вставка рассчитанного исторического результата в target. При продолжающейся загрузке нужно разделить старую историю и новые события так, чтобы не возникли пропуски или двойной вклад.

При конкурентных вставках POPULATE может пропустить новые строки; доступность этой опции зависит от формы view. Для backfill задают границу по времени или версии и сверяют исторический результат с исходником.

Refreshable materialized view

Refreshable view периодически выполняет запрос над доступными данными целиком. Она подходит для сложных соединений, исправлений истории и результата, который допустимо обновлять с задержкой.

CREATE MATERIALIZED VIEW refreshed_counts
REFRESH EVERY 1 HOUR
ENGINE = MergeTree
ORDER BY event_type AS
SELECT event_type, count() AS total
FROM events
GROUP BY event_type;

По умолчанию завершённый пересчёт атомарно заменяет предыдущий результат. Во время вычисления читатель продолжает видеть старую готовую версию. Режим APPEND добавляет новые результаты вместо замены; он требует отдельного смысла для накопленных снимков.

При каждом пересчёте view снова читает вход и расходует ресурсы. Между изменением источника и следующим успешным refresh остаётся задержка. Инкрементальный подход выбирают для корректно объединяемых новых вкладов, refreshable — когда проще заново получить согласованный результат из текущего источника.

Войти, чтобы отмечатьдальше →
10.13 →Kafka → ClickHouse: доставка и сбои