Пользователи часто спрашивают, когда следует использовать Materialized views, а когда — проекции. В этой статье мы рассмотрим ключевые различия между ними и объясним, почему в одних сценариях стоит выбрать одно, а в других — другое.
Сводка ключевых различий
В таблице ниже кратко приведены основные различия между materialized views и проекциями по разным аспектам.
| Aspect | Materialized views | Projections |
|---|---|---|
| Хранение и расположение данных | Хранят результаты в отдельной, явной целевой таблице и работают как insert triggers при вставке в исходную таблицу. | Проекции создают оптимизированные структуры данных, которые физически хранятся вместе с данными основной таблицы и невидимы для пользователя. |
| Механизм обновления | Работают синхронно при INSERT в исходную таблицу (для incremental materialized views). Примечание: их также можно обновлять по расписанию с помощью refreshable materialized views. |
Обновляются асинхронно в фоновом режиме после INSERT в основную таблицу. |
| Взаимодействие с запросами | Работа с Materialized Views требует выполнять запросы напрямую к целевой таблице, то есть при написании запросов нужно учитывать наличие materialized views. | Проекции автоматически выбираются оптимизатором запросов ClickHouse и прозрачны для пользователя: чтобы их использовать, не нужно изменять запросы к таблице с проекцией. Начиная с версии 25.6 также можно фильтровать более чем по одной проекции. |
Обработка UPDATE / DELETE |
Не реагируют автоматически на операции UPDATE или DELETE в исходной таблице, поскольку materialized views не знают об исходной таблице и работают только как insert triggers для вставки в исходную таблицу. Это может приводить к устареванию данных между исходной и целевой таблицами и требует обходных решений или периодического полного обновления. (через refreshable materialized view). |
По умолчанию несовместимы со строками DELETED (особенно при легковесных удалениях). lightweight_mutation_projection_mode (v24.7+) может включить совместимость. |
Поддержка JOIN |
Да. Refreshable materialized views можно использовать для сложной денормализации. Incremental materialized views срабатывают только при вставках в самую левую таблицу. | Нет. Операции JOIN не поддерживаются в определениях проекций для фильтрации материализованных данных. Однако запросы, объединяющие таблицы с проекциями, работают нормально — проекции оптимизируют доступ к отдельным таблицам. |
Секция WHERE в определении |
Да. Секции WHERE можно использовать для фильтрации данных перед materialization. |
Нет. Секции WHERE не поддерживаются в определениях проекций для фильтрации материализованных данных. |
| Возможности построения цепочек | Да, целевая таблица одной materialized view может быть источником для другой materialized view, что позволяет строить многоэтапные конвейеры. | Нет. Проекции нельзя выстраивать в цепочки. |
| Применимые движки таблиц | Можно использовать с различными движками исходных таблиц, но целевые таблицы обычно относятся к семейству MergeTree. |
Доступны только для движков таблиц семейства MergeTree. |
| Обработка сбоев | Сбой во время вставки данных означает потерю данных в целевой таблице, что может привести к несогласованности. | Сбои обрабатываются незаметно в фоновом режиме. Запросы могут без проблем сочетать материализованные и нематериализованные части. |
| Операционная нагрузка | Требуется явное создание целевой таблицы и часто ручная дозагрузка. Поддержание согласованности с UPDATE/DELETE повышает сложность. |
Проекции поддерживаются автоматически и остаются синхронизированными, поэтому обычно требуют меньше операционных усилий. |
Совместимость запросов с FINAL |
Обычно совместимы, но часто требуют GROUP BY по целевой таблице. |
Не работают с запросами FINAL. |
| Lazy materialization | Да. | Следите за проблемами совместимости проекций при использовании возможностей materialization. Может потребоваться установить query_plan_optimize_lazy_materialization = false |
| Параллельные реплики | Да. | Нет. |
optimize_read_in_order |
Да. | Да. |
| Легковесные обновления и удаления | Да. | Нет. |
Сравнение materialized views и проекций
Когда стоит выбирать materialized views
Вам стоит рассмотреть использование materialized views, если:
- Вы работаете с ETL в реальном времени и многоэтапными конвейерами данных: вам нужно выполнять сложные преобразования, агрегации или направлять данные по мере их поступления, в том числе через несколько этапов, выстраивая цепочку представлений.
- Вам нужна сложная денормализация: вам нужно заранее объединить данные из нескольких источников (таблиц, подзапросов или словарей) в одну таблицу, оптимизированную для запросов, особенно если допустимы периодические полные обновления с использованием refreshable materialized views.
- Вам нужен явный контроль над схемой: вам нужна отдельная, обособленная целевая таблица с собственной схемой и движком для хранения предварительно вычисленных результатов, что даёт больше гибкости при моделировании данных.
- Вы хотите фильтровать на этапе ингестии: вам нужно фильтровать данные до их материализации, уменьшая объём данных, записываемых в целевую таблицу.
Когда не стоит использовать materialized view
Стоит отказаться от использования materialized view в следующих случаях:
- Исходные данные часто обновляются или удаляются: без дополнительных механизмов, обеспечивающих согласованность между исходной и целевой таблицами, incremental materialized views могут устаревать и становиться несогласованными.
- В приоритете простота и автоматическая оптимизация: если вы не хотите управлять отдельными целевыми таблицами.
Когда стоит выбирать проекции
Проекции стоит использовать в следующих случаях:
- Оптимизация запросов к одной таблице: ваша основная цель — ускорить запросы к одной базовой таблице за счёт альтернативных порядков сортировки, оптимизации фильтров по столбцам, не входящим в первичный ключ, или предварительного вычисления агрегаций для одной таблицы.
- Вам нужна прозрачность запросов: вы хотите, чтобы запросы без изменений выполнялись к исходной таблице, а ClickHouse сам выбирал оптимальную структуру данных для конкретного запроса.
Когда следует избегать проекций
Следует избегать использования проекций в следующих случаях:
- Требуются сложные преобразования данных или многоэтапный ETL: определения проекций не поддерживают операции
JOIN, их нельзя выстраивать в цепочку для создания многошаговых конвейеров, и они не поддерживают некоторые возможности SQL, такие как оконные функции или сложные выраженияCASE. Хотя запросы к таблицам с проекциями могут свободно использоватьJOIN, сами проекции не подходят для сложных преобразований данных. - Требуется явная фильтрация материализованных данных: проекции не поддерживают секции
WHEREв своих определениях для фильтрации данных, которые материализуются в саму проекцию. - Используются движки таблиц, отличные от
MergeTree: проекции доступны только для таблиц, использующих семейство движковMergeTree. FINAL-запросы критически важны: проекции не работают с запросамиFINAL, которые иногда используются для дедупликации.- Вам нужны параллельные реплики, так как проекции их не поддерживают.
Краткое резюме
Materialized views и проекции — это мощные инструменты для оптимизации запросов и преобразования данных, и в целом мы рекомендуем не рассматривать их как взаимоисключающие варианты. Напротив, их можно использовать совместно, чтобы получить максимум от ваших запросов. Поэтому выбор между materialized views и проекциями в ClickHouse в первую очередь зависит от вашего конкретного сценария использования и характера доступа к данным.
В качестве общего практического правила стоит рассмотреть использование materialized views, когда вам нужно агрегировать данные из одной или нескольких исходных таблиц в целевую таблицу или выполнять сложные преобразования в большом масштабе. Materialized views отлично подходят для переноса ресурсоёмких агрегаций с этапа выполнения запроса на этап вставки данных. Это хороший выбор для ежедневных или ежемесячных rollup, панелей мониторинга в реальном времени и сводных данных.
С другой стороны, проекции стоит использовать, когда нужно оптимизировать запросы, которые фильтруют по другим столбцам, а не по тем, которые входят в первичный ключ таблицы и определяют физический порядок данных на диске. Они особенно полезны, когда изменить первичный ключ таблицы уже невозможно или когда характер доступа к данным более разнообразен, чем может охватить первичный ключ.