Дашборд Отто висит на экране в офисе и раз в минуту пересчитывает график «открытия приложения по часам». Каждый раз 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 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.