Проекции
Проекции хранят данные в формате, оптимизирующем выполнение запросов, эта функция полезна для:
- Выполнения запросов по колонкам, которые не являются частью первичного ключа
- Предагрегирования колонок, что уменьшает как вычисления, так и ввод-вывод
Вы можете определить одну или несколько проекций для таблицы, и во время анализа запроса ClickHouse выберет проекцию с наименьшим объемом данных для сканирования, не изменяя запрос, предоставленный пользователем.
Проекции создадут внутреннюю скрытую таблицу, что означает, что потребуется больше ввода-вывода и места на диске. Например, если проекция определила другой первичный ключ, все данные из оригинальной таблицы будут продублированы.
Вы можете увидеть больше технических деталей о том, как проекции работают внутренне на этой странице.
Пример фильтрации без использования первичных ключей
Создание таблицы:
Используя ALTER TABLE, мы могли бы добавить проекцию в существующую таблицу:
Вставка данных:
Проекция позволит нам быстро фильтровать по user_name, даже если в оригинальной таблице user_name не был определен как PRIMARY_KEY.
В момент выполнения запроса ClickHouse определил, что будет обработано меньше данных, если использовать проекцию, поскольку данные отсортированы по user_name.
Чтобы проверить, использует ли запрос проекцию, мы могли бы просмотреть таблицу system.query_log. В поле projections мы имеем имя использованной проекции или пустое значение, если ни одна не была использована:
Пример запроса предагрегации
Создание таблицы с проекцией:
Вставка данных:
Мы выполним первый запрос с использованием GROUP BY по полю user_agent, этот запрос не будет использовать определенную проекцию, так как предагрегация не совпадает.
Чтобы использовать проекцию, мы можем выполнить запросы, которые выбирают часть или все поля предагрегации и GROUP BY.
Как упоминалось ранее, мы могли бы просмотреть таблицу system.query_log. В поле projections мы имеем имя использованной проекции или пустое значение, если ни одна не была использована:
Обычная проекция с полем _part_offset
Создание таблицы с обычной проекцией, использующей поле _part_offset:
Вставка некоторых тестовых данных:
Использование _part_offset как вторичного индекса
Поле _part_offset сохраняет свое значение во время слияний и мутаций, что делает его ценным для вторичного индексирования. Мы можем использовать это в запросах:
Манипуляции с проекциями
Доступны следующие операции с проекциями:
ADD PROJECTION
ALTER TABLE [db.]name [ON CLUSTER cluster] ADD PROJECTION [IF NOT EXISTS] name ( SELECT <COLUMN LIST EXPR> [GROUP BY] [ORDER BY] ) - Добавляет описание проекции в метаданные таблиц.
DROP PROJECTION
ALTER TABLE [db.]name [ON CLUSTER cluster] DROP PROJECTION [IF EXISTS] name - Удаляет описание проекции из метаданных таблиц и удаляет файлы проекции с диска. Реализовано как мутация.
MATERIALIZE PROJECTION
ALTER TABLE [db.]table [ON CLUSTER cluster] MATERIALIZE PROJECTION [IF EXISTS] name [IN PARTITION partition_name] - Запрос перестраивает проекцию name в партиции partition_name. Реализовано как мутация.
CLEAR PROJECTION
ALTER TABLE [db.]table [ON CLUSTER cluster] CLEAR PROJECTION [IF EXISTS] name [IN PARTITION partition_name] - Удаляет файлы проекции с диска, не удаляя описание. Реализовано как мутация.
Команды ADD, DROP и CLEAR являются легковесными в том смысле, что они изменяют только метаданные или удаляют файлы.
Кроме того, они реплицируются, синхронизируя метаданные проекций через ClickHouse Keeper или ZooKeeper.
Манипуляции с проекциями поддерживаются только для таблиц с движком *MergeTree (включая реплицируемые варианты).