Learning Platform
Глоссарий Troubleshooting
Урок 05.06 · 15 мин
Средний
Decision FrameworkMVProjectionRefreshable MVdbtQuery Acceleration

MV vs Projection vs Refreshable MV vs dbt

Мы разобрали четыре механизма ускорения запросов. Каждый решает свою задачу, но в реальных проектах выбор не всегда очевиден. Этот урок даёт фреймворк: матрицу решений по 5 критериям и маппинг use case на подход.


Матрица решений

Матрица решений: 4 подхода по 5 критериям
КритерийКритерий сравнения четырёх подходов к ускорению запросов
Incremental MVИнкрементальная MV: триггер на INSERT, обрабатывает только новые строки из INSERT-блока
ProjectionПроекция: встроенная в таблицу дополнительная копия данных с альтернативной сортировкой или агрегацией
Refreshable MVRefreshable MV: периодический полный пересчёт по расписанию, GA с ClickHouse 24.10
dbtdbt: внешний инструмент трансформации данных с версионированием, тестами и CI/CD
LatencyЗадержка между записью данных и их доступностью в ускоренном представлении
Real-timeДанные доступны сразу после INSERT -- MV обрабатывает каждый INSERT-блок в реальном времени
Real-timeДанные доступны сразу -- проекция обновляется неявно при каждом INSERT как часть записи part
ScheduledДанные обновляются по расписанию: REFRESH EVERY / AFTER. Задержка от минут до часов
ScheduledДанные обновляются по расписанию dbt run. Задержка от минут до часов, зависит от CI/CD pipeline
SQL гибкостьНасколько свободно можно писать SQL в определении представления или трансформации
ОграниченSQL ограничен: нет JOINs, UNION, table functions. Обрабатывает только строки из одного INSERT-блока
АвтоАвтоматическое переписывание запроса -- не нужно менять SQL. ClickHouse сам решает, использовать ли проекцию
Полный SQLПолная свобода SQL: JOINs, UNION, подзапросы, table functions, url(), s3(). Полный пересчёт даёт доступ ко всем данным
Полный SQLПолная свобода SQL через Jinja-шаблоны. Дополнительно: ref(), source(), тесты, документация
StorageДополнительное дисковое пространство, необходимое для хранения ускоренного представления
Отдельная таблицаОтдельная target-таблица. Размер зависит от агрегации -- может быть значительно меньше source
Дупликация в partДополнительная копия данных внутри каждого part. Нет отдельной таблицы, но storage удваивается для проецируемых столбцов
Отдельная таблицаОтдельная target-таблица. При REPLACE -- полная копия результата SELECT. При APPEND -- растёт со временем
Отдельная таблицаОтдельная таблица, создаваемая dbt. Размер зависит от SQL-трансформации
BackfillingКак заполнить представление историческими данными, существовавшими до его создания
РучнойРучной: INSERT INTO target SELECT FROM source. MV не видит данные, вставленные до её создания
АвтоАвтоматический: ALTER TABLE MATERIALIZE PROJECTION. ClickHouse пересчитывает проекцию для всех существующих parts
АвтоАвтоматический: каждый refresh пересчитывает весь SELECT. Исторические данные включаются автоматически
АвтоАвтоматический: dbt run пересоздаёт таблицу из полного SELECT. Исторические данные включаются автоматически
СложностьУровень сложности настройки и поддержки данного подхода
СредняяСредняя: нужно понимать trigger-on-insert семантику, -State/-Merge паттерн, backfilling, pitfalls с ALTER TABLE
НизкаяНизкая: добавить PROJECTION в CREATE TABLE. ClickHouse автоматически обновляет и использует проекцию
НизкаяНизкая: REFRESH EVERY / AFTER + DEPENDS ON. Мониторинг через system.view_refreshes
СредняяСредняя: внешний инструмент, требует Python, pip install, profiles.yml, CI/CD интеграцию

Маппинг 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() для отслеживания зависимостей между моделями
TIP

Если трансформация — это разовый отчёт или внутренний ETL из 2-3 шагов, используйте refreshable MV. Если это production-система с 10+ моделями, несколькими инженерами и требованием CI/CD — используйте dbt.


Ключевые выводы

  1. Real-time данные — инкрементальная MV. Нет альтернативы для zero-latency агрегации.
  2. Альтернативная сортировка — проекция. Минимальная сложность, автоматическое использование.
  3. Периодические отчёты с JOINs — refreshable MV. Полная свобода SQL, встроенный каскад.
  4. Сложные ETL с CI/CD — dbt. Тесты, версионирование, lineage оправдывают overhead.
  5. Подходы комбинируются: real-time MV + projection + refreshable MV могут сосуществовать на одной source-таблице.

Проверьте понимание

Результат: 0 из 0
Аналитический
Вопрос 1 из 3. Команда строит real-time дашборд для мониторинга входящих событий: count events/sec, uniq users за последнюю минуту. Данные должны быть актуальны в течение секунды после INSERT. Какой подход?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 7