> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Materialized views и проекции

> Статья, сравнивающая Materialized views и проекции в ClickHouse, включая сценарии использования, производительность и ограничения.

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

<div id="key-differences">
  ## Сводка ключевых различий
</div>

В таблице ниже кратко приведены основные различия между 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`](/ru/reference/settings/session-settings/optimize#optimize_read_in_order) | Да. | Да. |
| Легковесные обновления и удаления | Да. | Нет. |

<div id="choose-between">
  ## Сравнение materialized views и проекций
</div>

<div id="choosing-materialized-views">
  ### Когда стоит выбирать materialized views
</div>

Вам стоит рассмотреть использование materialized views, если:

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

<div id="avoid-materialized-views">
  ### Когда не стоит использовать materialized view
</div>

Стоит отказаться от использования materialized view в следующих случаях:

* **Исходные данные часто обновляются или удаляются**: без дополнительных механизмов, обеспечивающих согласованность между исходной и целевой таблицами, incremental materialized views могут устаревать и становиться несогласованными.
* **В приоритете простота и автоматическая оптимизация**: если вы не хотите управлять отдельными целевыми таблицами.

<div id="choosing-projections">
  ### Когда стоит выбирать проекции
</div>

Проекции стоит использовать в следующих случаях:

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

<div id="avoid-projections">
  ### Когда следует избегать проекций
</div>

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

* **Требуются сложные преобразования данных или многоэтапный ETL**: определения проекций не поддерживают операции `JOIN`, их нельзя выстраивать в цепочку для создания многошаговых конвейеров, и они не поддерживают некоторые возможности SQL, такие как оконные функции или сложные выражения `CASE`. Хотя запросы к таблицам с проекциями могут свободно использовать `JOIN`, сами проекции не подходят для сложных преобразований данных.
* **Требуется явная фильтрация материализованных данных**: проекции не поддерживают секции `WHERE` в своих определениях для фильтрации данных, которые материализуются в саму проекцию.
* **Используются движки таблиц, отличные от `MergeTree`**: проекции доступны только для таблиц, использующих семейство движков `MergeTree`.
* `FINAL`-запросы критически важны: проекции не работают с запросами `FINAL`, которые иногда используются для дедупликации.
* Вам нужны [параллельные реплики](/ru/products/cloud/features/infrastructure/parallel-replicas), так как проекции их не поддерживают.

<div id="summary">
  ## Краткое резюме
</div>

Materialized views и проекции — это мощные инструменты для оптимизации запросов и преобразования данных, и в целом мы рекомендуем не рассматривать их как взаимоисключающие варианты. Напротив, их можно использовать совместно, чтобы получить максимум от ваших запросов. Поэтому выбор между materialized views и проекциями в ClickHouse в первую очередь зависит от вашего конкретного сценария использования и характера доступа к данным.

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

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