Раздел 38 · ClickHouse и аналитические базы

Материализованные представления: предагрегация на лету

junior~15 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Дашборд Отто висит на экране в офисе и раз в минуту пересчитывает график «открытия приложения по часам». Каждый раз ClickHouse проходит по всем событиям месяца. Сейчас их сотни тысяч, через год будут миллиарды, а ответ на графике меняется только в последней точке. Пересчитывать весь месяц ради последнего часа расточительно. Лучше держать готовые числа и дописывать к ним новое. Этим и занимаются материализованные представления.

Счётчик на двери

Магазин хочет знать, сколько покупателей заходит по часам. Можно каждый вечер пересматривать запись камеры за весь день. А можно повесить на дверь счётчик, который щёлкает при каждом входе, и раз в час записывать показания. Второй способ считает понемногу и сразу, поэтому готовый ответ есть всегда.

Как это устроено в ClickHouse

Материализованное представление в ClickHouse это не сохранённый результат запроса, как в PostgreSQL, а триггер на вставку. Каждый раз, когда в исходную таблицу приходит INSERT, представление выполняет свой SELECT над только что вставленной пачкой и дописывает результат в целевую таблицу.

Собирается из трёх частей:

-- 1. Целевая таблица: здесь будут лежать готовые числа
CREATE TABLE hourly_opens (
    hour DateTime,
    platform LowCardinality(String),
    opens UInt64
) ENGINE = SummingMergeTree
ORDER BY (hour, platform);

-- 2. Представление: что считать на каждую вставку и куда писать
CREATE MATERIALIZED VIEW hourly_opens_mv TO hourly_opens AS
SELECT toStartOfHour(ts) AS hour, platform, count() AS opens
FROM events
WHERE kind = 'open'
GROUP BY hour, platform;

-- 3. Дашборд читает целевую таблицу
SELECT hour, sum(opens) FROM hourly_opens GROUP BY hour ORDER BY hour;

Почему целевая таблица на SummingMergeTree и почему в запросе дашборда всё равно sum? Каждая вставка событий даёт свою пачку итогов. Если события за 9 утра пришли тремя вставками, в hourly_opens будет три строки за 9 утра. При слиянии частей SummingMergeTree сложит их в одну, но слияние случится когда-нибудь, а дашборд нужен сейчас. Это то самое правило из урока 10.

урок из курса

Урок из курса «ClickHouse и аналитические базы». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.