MV vs Projection vs Refreshable MV vs dbt
Мы разобрали четыре механизма ускорения запросов. Каждый решает свою задачу, но в реальных проектах выбор не всегда очевиден. Этот урок даёт фреймворк: матрицу решений по 5 критериям и маппинг use case на подход.
Матрица решений
Маппинг use case на подход
Определите характеристики вашей задачи и выберите подход:
Real-time счётчики и агрегация
Нужны актуальные метрики сразу после INSERT: page views, click counters, real-time дашборды.
Подход: Инкрементальная MV + SummingMergeTree / AggregatingMergeTree. Триггер на INSERT обеспечивает актуальность без задержки.
Альтернативный порядок сортировки
Таблица отсортирована по (date, user_id), но часть запросов фильтрует по event_type. Нужен эффективный доступ без изменения основного ORDER BY.
Подход: Projection. Добавьте проекцию с ORDER BY event_type. ClickHouse автоматически переключит запрос на проекцию, если она читает меньше гранул. Минимальные усилия, нет отдельной таблицы.
Периодические отчёты с JOINs
Ежечасный отчёт, объединяющий данные из нескольких таблиц: events + users + products. Допустима задержка в 1 час.
Подход: Refreshable MV. REFRESH EVERY 1 HOUR + полная свобода SQL (JOINs без ограничений). DEPENDS ON для каскадных зависимостей.
Сложные ETL-конвейеры с CI/CD
Многоэтапная трансформация данных: staging, cleaning, enrichment, aggregation. Нужны тесты, версионирование, code review, rollback.
Подход: dbt. Jinja-шаблоны, ref() для зависимостей, тесты данных, CI/CD pipeline. Overhead внешнего инструмента оправдан масштабом и процессом.
Комбинирование подходов
В реальных проектах подходы комбинируются. Типичный паттерн:
raw_events (MergeTree)
|
|-- Incremental MV --> real_time_counters (SummingMergeTree)
| для real-time дашборда
|
|-- Projection (ORDER BY user_id)
| для ad-hoc запросов по user_id
|
|-- Refreshable MV (REFRESH EVERY 1 DAY) --> daily_report
для ежедневного отчёта с JOINs
Каждый подход решает свою задачу. Нет единственного правильного выбора — есть правильная комбинация.
Когда dbt предпочтительнее refreshable MV
dbt и refreshable MV решают похожую задачу (периодическая трансформация), но dbt добавляет:
- Версионирование: SQL-модели в git, code review через PR
- Тесты: schema tests (not_null, unique), data tests (custom SQL assertions)
- Документация: автоматическая генерация DAG-визуализации и описания моделей
- CI/CD: pre-merge тестирование трансформаций, автоматический deploy
- Lineage: ref() для отслеживания зависимостей между моделями
Если трансформация — это разовый отчёт или внутренний ETL из 2-3 шагов, используйте refreshable MV. Если это production-система с 10+ моделями, несколькими инженерами и требованием CI/CD — используйте dbt.
Ключевые выводы
- Real-time данные — инкрементальная MV. Нет альтернативы для zero-latency агрегации.
- Альтернативная сортировка — проекция. Минимальная сложность, автоматическое использование.
- Периодические отчёты с JOINs — refreshable MV. Полная свобода SQL, встроенный каскад.
- Сложные ETL с CI/CD — dbt. Тесты, версионирование, lineage оправдывают overhead.
- Подходы комбинируются: real-time MV + projection + refreshable MV могут сосуществовать на одной source-таблице.