Перейти к основному содержанию
Перейти к основному содержанию

Материализованные представления и проекции

Один из частых вопросов пользователей — когда следует использовать материализованные представления, а когда проекции. В этой статье мы рассмотрим ключевые различия между ними и разберёмся, почему в определённых сценариях стоит предпочесть один подход другому.

Сводка ключевых различий

В таблице ниже приведены ключевые различия между материализованными представлениями и проекциями по различным аспектам.

АспектМатериализованные представленияПроекции
Data storage and locationСохраняют свои результаты в отдельной, явно заданной целевой таблице, выступая в роли триггеров вставки при INSERT в исходную таблицу.Проекции создают оптимизированные структуры данных, которые физически хранятся рядом с основными данными таблицы и невидимы для пользователя.
Update mechanismРаботают синхронно при INSERT в исходную таблицу (для инкрементальных материализованных представлений). Примечание: их также можно планировать по расписанию с помощью обновляемых материализованных представлений.Асинхронные обновления в фоновом режиме при INSERT в основную таблицу.
Query interactionРабота с материализованными представлениями требует прямого выполнения запросов к целевой таблице, то есть пользователи должны знать о существовании материализованных представлений при написании запросов.Проекции автоматически выбираются оптимизатором запросов ClickHouse и являются прозрачными в том смысле, что пользователю не нужно изменять свои запросы к таблице с проекцией, чтобы её использовать. Начиная с версии 25.6 также можно фильтровать более чем по одной проекции.
Handling UPDATE / DELETEНе реагируют автоматически на операции UPDATE или DELETE над исходной таблицей, так как материализованные представления не обладают информацией об исходной таблице и работают только как триггеры вставки в исходную таблицу. Это может приводить к потенциальной несвежести данных между исходной и целевой таблицами и требует обходных решений или периодического полного обновления (через обновляемое материализованное представление).По умолчанию несовместимы с удалёнными (DELETED) строками (особенно с облегчёнными удалениями — lightweight deletes). Параметр lightweight_mutation_projection_mode (v24.7+) может включить совместимость.
JOIN supportДа. Обновляемые материализованные представления могут использоваться для сложной денормализации. Инкрементальные материализованные представления срабатывают только при вставках в самую левую таблицу.Нет. Операции JOIN не поддерживаются в определениях проекций для фильтрации материализованных данных. Однако запросы, которые делают JOIN таблиц с проекциями, работают нормально — проекции оптимизируют доступ к отдельным таблицам.
WHERE clause in definitionДа. Условия WHERE могут быть включены для фильтрации данных до материализации.Нет. Условия WHERE не поддерживаются в определениях проекций для фильтрации материализованных данных.
Chaining capabilitiesДа, целевая таблица одного материализованного представления может быть источником для другого материализованного представления, что позволяет строить многоступенчатые конвейеры.Нет. Проекции нельзя связывать в цепочку.
Applicable table enginesМогут использоваться с различными движками исходных таблиц, но целевые таблицы обычно принадлежат семейству MergeTree.Доступны только для движков таблиц семейства MergeTree.
Failure handlingСбой во время вставки данных означает потерю данных в целевой таблице, что может привести к несогласованности данных.Сбои тихо обрабатываются в фоновом режиме. Запросы могут бесшовно комбинировать материализованные и нематериализованные части данных.
Operational overheadТребуют явного создания целевой таблицы и часто ручного дозаполнения (backfill). Управление согласованностью данных при UPDATE/DELETE повышает сложность.Проекции автоматически поддерживаются и синхронизируются и, как правило, создают меньшую операционную нагрузку.
FINAL query compatibilityВ целом совместимы, но часто требуют GROUP BY по целевой таблице.Не работают с запросами FINAL.
Lazy materializationДа.Следите за проблемами совместимости проекций при использовании механизмов ленивой материализации. Возможно, потребуется установить query_plan_optimize_lazy_materialization = false.
Parallel replicasДа.Нет.
optimize_read_in_orderДа.Да.
Lightweight updates and deletesДа.Нет.

Сравнение материализованных представлений и проекций

Когда стоит выбирать материализованные представления

Использование материализованных представлений стоит рассмотреть, когда:

  • Вы работаете с ETL в режиме реального времени и многостадийными конвейерами обработки данных: Нужно выполнять сложные преобразования, агрегации или маршрутизацию данных по мере их поступления, возможно, через несколько стадий, связывая представления в цепочки.
  • Вам требуется сложная денормализация: Нужно заранее объединить данные из нескольких источников (таблиц, подзапросов или словарей) в одну таблицу, оптимизированную для запросов, особенно если допустимы периодические полные обновления с использованием обновляемых материализованных представлений.
  • Вам нужен явный контроль над схемой: Требуется отдельная целевая таблица с собственной схемой и движком для предварительно вычисленных результатов, что обеспечивает большую гибкость при моделировании данных.
  • Вы хотите фильтровать на этапе ингестии: Нужно отфильтровать данные до того, как они будут материализованы, уменьшая объём данных, записываемых в целевую таблицу.

Когда следует избегать материализованных представлений

Следует рассмотреть отказ от использования материализованных представлений, когда:

  • Исходные данные часто обновляются или удаляются: Без дополнительных стратегий поддержания согласованности между исходными и целевыми таблицами инкрементальные материализованные представления могут устаревать и становиться несогласованными.
  • Предпочитаются простота и автоматическая оптимизация: Если вы не хотите управлять отдельными целевыми таблицами.

Когда следует использовать проекции

Рекомендуется рассматривать использование проекций, когда:

  • Оптимизируете запросы для одной таблицы: ваша основная цель — ускорить запросы к одной базовой таблице за счёт задания альтернативных порядков сортировки, оптимизации фильтров по столбцам, которые не входят в первичный ключ, или предварительного вычисления агрегаций для одной таблицы.
  • Вам нужна прозрачность запросов: вы хотите, чтобы запросы по-прежнему выполнялись к исходной таблице без изменений, полагаясь на ClickHouse при выборе наилучшего расположения данных для конкретного запроса.

Когда следует избегать проекций

Рекомендуется избегать использования проекций в следующих случаях:

  • Требуется сложная трансформация данных или многоэтапный ETL: Определения проекций не поддерживают операции JOIN, не могут быть объединены в цепочки для построения многошаговых конвейеров и не работают с некоторыми возможностями SQL, такими как оконные функции или сложные выражения CASE. Хотя запросы к таблицам с проекциями могут свободно использовать JOIN, сами проекции не подходят для сложной трансформации данных.
  • Нужна явная фильтрация материализованных данных: Проекции не поддерживают использование предложения WHERE в определении для фильтрации данных, которые материализуются в саму проекцию.
  • Используются табличные движки, отличные от MergeTree: Проекции доступны исключительно для таблиц, использующих семейство движков MergeTree.
  • Запросы с FINAL являются критически важными: проекции не работают с запросами FINAL, которые иногда используются для дедупликации.
  • Вам нужны параллельные реплики, так как они не поддерживаются при использовании проекций.

Резюме

Материализованные представления и проекции — это мощные инструменты в вашем арсенале для оптимизации запросов и преобразования данных, и в целом мы не рекомендуем рассматривать их использование как взаимоисключающий выбор. Вместо этого их можно применять взаимодополняющим образом, чтобы получить максимальную отдачу от запросов. Таким образом, выбор между материализованными представлениями и проекциями в ClickHouse на самом деле зависит от конкретного сценария использования и паттернов доступа.

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

С другой стороны, имеет смысл использовать проекции, когда необходимо оптимизировать запросы, которые фильтруют по другим столбцам, чем те, что используются в первичном ключе таблицы, определяющем физический порядок данных на диске. Они особенно полезны, когда изменить первичный ключ таблицы больше невозможно или когда ваши паттерны доступа более разнообразны, чем то, что может обеспечить первичный ключ.