Перейти к основному содержанию
На этой странице объясняется, что такое проекции, как их использовать и какие есть способы управления проекциями.

Обзор проекций

Проекции хранят данные в формате, оптимизированном для выполнения запросов. Эта возможность полезна в следующих случаях:
  • Выполнение запросов по столбцу, который не входит в первичный ключ
  • Предварительная агрегация столбцов, что снижает как вычислительные затраты, так и объём операций ввода-вывода
Для таблицы можно определить одну или несколько проекций, и на этапе анализа запроса ClickHouse выберет проекцию, для которой требуется просканировать меньше всего данных, не изменяя запрос, заданный пользователем.
Использование дискаПроекции внутренне создают новую скрытую таблицу, а это значит, что потребуется больше операций ввода-вывода и места на диске. Например, если для проекции задан другой первичный ключ, все данные из исходной таблицы будут дублироваться.
Более подробную техническую информацию о том, как проекции работают изнутри, см. на этой странице.

Использование проекций

Пример фильтрации без использования первичных ключей

Создание таблицы:
С помощью ALTER TABLE можно добавить проекцию в существующую таблицу:
Вставка данных:
Проекция позволит нам быстро фильтровать по user_name, даже если в исходной таблице user_name не был определён как PRIMARY_KEY. Во время выполнения запроса ClickHouse определяет, что при использовании проекции будет обработано меньше данных, так как данные упорядочены по user_name.
Чтобы убедиться, что запрос использует проекцию, можно проверить таблицу system.query_log. В поле projections указано имя использованной проекции или пустое значение, если проекция не использовалась:

Пример запроса с предварительной агрегацией

Создайте таблицу с проекцией projection_visits_by_user:
Вставьте данные:
Выполните первый запрос с GROUP BY, используя поле user_agent. Этот запрос не будет использовать проекцию, так как предварительная агрегация ему не соответствует.
Чтобы использовать проекцию, можно выполнять запросы, выбирающие часть или все поля предварительной агрегации и GROUP BY:
Как уже упоминалось, вы можете просмотреть таблицу system.query_log, чтобы понять, использовалась ли проекция. Поле projections показывает имя использованной проекции. Оно будет пустым, если проекция не использовалась:

Создание и использование индексов-проекций

Создание индекса-проекции:
Вставим несколько примеров данных:
Поле _part_offset сохраняет своё значение при слияниях и мутациях, что делает его полезным для вторичной индексации. Это можно использовать в запросах:

Управление проекциями

Доступны следующие операции с проекциями:

ADD PROJECTION

Используйте приведённый ниже оператор, чтобы добавить описание проекции в метаданные таблицы:

Конструкция WITH SETTINGS

WITH SETTINGS определяет настройки уровня проекции, которые задают, как проекция хранит данные (например, index_granularity или index_granularity_bytes). Они напрямую соответствуют настройкам таблиц семейства MergeTree, но применяются только к этой проекции. Пример:
Настройки проекции переопределяют действующие настройки таблицы для этой проекции с учетом правил проверки (например, недопустимые или несовместимые переопределения будут отклонены).

DROP PROJECTION

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

MATERIALIZE PROJECTION

Используйте приведённый ниже оператор, чтобы перестроить проекцию name в партиции partition_name. Это реализовано как мутация.

CLEAR PROJECTION

Используйте приведённый ниже оператор, чтобы удалить с диска файлы проекции, не удаляя её описание. Это реализовано как мутация.
Команды ADD, DROP и CLEAR считаются легковесными, поскольку изменяют только метаданные или удаляют файлы. Кроме того, эти команды реплицируются и синхронизируют метаданные проекций через ClickHouse Keeper или ZooKeeper.
Операции с проекциями поддерживаются только для таблиц с движком таблица семейства *MergeTree (включая реплицируемые варианты).

Управление поведением слияния проекций

Когда вы выполняете запрос, ClickHouse выбирает, читать ли данные из исходной таблицы или из одной из её проекций. Это решение принимается отдельно для каждой части таблицы. Как правило, ClickHouse старается читать как можно меньше данных и использует несколько приёмов, чтобы определить, из какой части лучше читать, например сэмплирование по первичному ключу части. В некоторых случаях у частей исходной таблицы нет соответствующих частей проекций. Это может происходить, например, потому что создание проекции для таблицы в SQL по умолчанию выполняется «лениво»: оно затрагивает только вновь вставленные данные, а существующие части не изменяются. Поскольку одна из проекций уже содержит заранее вычисленные агрегированные значения, ClickHouse старается читать из соответствующих частей проекций, чтобы избежать повторной агрегации во время выполнения запроса. Если у конкретной части нет соответствующей части проекции, запрос выполняется по исходной части. Но что происходит, если строки в исходной таблице нетривиально изменяются из-за нетривиальных фоновых слияний частей данных? Например, предположим, что таблица использует движок таблицы ReplacingMergeTree. Если во время слияния в нескольких входных частях обнаруживается одна и та же строка, сохраняется только самая новая версия строки (из части, вставленной последней), а все более старые версии отбрасываются. Аналогично, если таблица использует движок таблицы AggregatingMergeTree, операция слияния может сворачивать одинаковые строки во входных частях (на основе значений первичного ключа) в одну строку, чтобы обновить промежуточные состояния агрегации. До ClickHouse v24.8 части проекций либо незаметно рассинхронизировались с основными данными, либо некоторые операции, такие как обновления и удаления, вообще нельзя было выполнять, поскольку база данных автоматически генерировала исключение, если у таблицы были проекции. Начиная с v24.8, новый параметр уровня таблицы deduplicate_merge_projection_mode управляет поведением в случае, если вышеупомянутые нетривиальные фоновые операции слияния происходят в частях исходной таблицы. Мутации удаления — ещё один пример операций слияния частей, при которых удаляются строки в частях исходной таблицы. Начиная с v24.7, также есть параметр для управления поведением в отношении мутаций удаления, запускаемых легковесными удалениями: lightweight_mutation_projection_mode. Ниже приведены возможные значения для deduplicate_merge_projection_mode и lightweight_mutation_projection_mode:
  • throw (по умолчанию): генерируется исключение, что не позволяет частям проекций рассинхронизироваться.
  • drop: Затронутые части таблицы проекций удаляются. Для таких частей запросы будут выполняться по исходной части таблицы.
  • rebuild: Затронутая часть проекции перестраивается, чтобы оставаться согласованной с данными в части исходной таблицы.

Ограничения

Нельзя использовать столбец ALIAS в предложении ORDER BY проекции. Например:
Столбцы ALIAS физически не хранятся и вычисляются на лету во время выполнения запроса, поэтому они недоступны при записи части проекции, когда вычисляется выражение сортировки. Вместо этого используйте столбцы MATERIALIZED или встроите выражение напрямую:

См. также

Последнее изменение 2 июля 2026 г.