Гайды
Введение в ClickHouse для аналитики
MergeTree, PARTITION BY и ORDER BY, батч-вставки, типы данных, FORMAT и отличие OLAP от OLTP.
~12 мин чтения
Введение в ClickHouse для аналитики
ClickHouse — колоночная СУБД для OLAP: агрегации по большим объёмам, отчёты, логи, метрики. Строки хранятся колонками, сжатие сильное, векторизация запросов. Это не замена PostgreSQL для OLTP: вставки батчами, точечные UPDATE строки дороже.
Тонкая настройка сервера и запросов — в «Настройка и оптимизация ClickHouse». Официальная документация: clickhouse.com/docs.
1. Когда ClickHouse уместен
| Подходит | Менее подходит |
|---|---|
| Витрины, BI, события, телеметрия | Частые точечные UPDATE одной строки |
| Скан миллиардов строк + GROUP BY | Много мелких конкурирующих вставок по одной строке |
2. Установка и клиент
docker run -d --name clickhouse -p 8123:8123 -p 9000:9000 clickhouse/clickhouse-server
- 8123 — HTTP.
- 9000 — нативный протокол (
clickhouse-client).
docker exec -it clickhouse clickhouse-client -q "SELECT version()"
3. База, таблица, MergeTree
CREATE DATABASE IF NOT EXISTS analytics;
CREATE TABLE analytics.events (
event_date Date,
event_time DateTime,
user_id UInt64,
event String,
properties String
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id, event_time);
MergeTree— основной движок; данные партами, фоном merge.PARTITION BY— грубое разбиение (часто месяц); удобноDROP PARTITIONдля TTL.ORDER BY— сортировка внутри парта и разреженный primary index по гранулам.
4. Вставка — батчи
Избегайте микро-вставок по одной строке: много мелких parts → нагрузка на merge.
INSERT INTO analytics.events VALUES
('2025-04-01', '2025-04-01 10:00:00', 1, 'page_view', '{}'),
('2025-04-01', '2025-04-01 10:00:01', 2, 'click', '{"x":1}');
Файлы CSV/Parquet, INSERT SELECT, интеграции — см. документацию.
Через HTTP (8123) удобно грузить батчи: INSERT ... FORMAT JSONEachRow с телом запроса; для больших файлов — async_insert и параметры max_insert_block_size (см. доку вашей версии). Из приложений чаще используют нативный TCP (9000) или официальные клиенты — меньше оверхеда, чем у HTTP.
5. Чтение и агрегации
SELECT
toStartOfDay(event_time) AS day,
event,
count() AS cnt
FROM analytics.events
WHERE event_date >= '2025-04-01' AND event_date < '2025-05-01'
GROUP BY day, event
ORDER BY cnt DESC
LIMIT 20;
count() без аргумента оптимизирован.
6. Типы данных (обзор)
UInt* / Int*, String, FixedString(N), Date, DateTime, DateTime64, Decimal(P, S), Array(T), Nested, Tuple, JSON (зависит от версии). Не храните всё в String, если есть подходящий числовой/датовый тип.
Для низкой кардинальности (страна, тип события, код ошибки) используйте LowCardinality(String) — меньше RAM и быстрее группировки при умеренном числе уникальных значений.
7. ORDER BY и «первичный ключ»
В MergeTree ключ сортировки задаёт локальность и разреженный индекс; уникальность как в PostgreSQL не гарантируется — это не классический PK.
8. FORMAT
SELECT * FROM analytics.events LIMIT 10 FORMAT JSONEachRow;
9. Материализованные представления
MaterializedView на MergeTree может складывать агрегаты в целевую таблицу при вставке в «сырьё» — типичный паттерн витрин (синтаксис зависит от версии).
10. Типичные ошибки
| Ошибка | Эффект |
|---|---|
| Микро-батчи | Слишком много parts |
ORDER BY не совпадает с фильтрами | Лишнее сканирование |
| ClickHouse как key-value | Неверный инструмент |
| Удаление старого без партиций | Дорогие мутации вместо DROP PARTITION |
| Дедуп строк по ключу в витрине | Вместо «уникального индекса» смотрите ReplacingMergeTree / AggregatingMergeTree под задачу |
Связанные материалы
- Настройка и оптимизация ClickHouse
- EXPLAIN ANALYZE в PostgreSQL — сравнение культуры диагностики планов в OLTP