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