Проекции
Проекции хранят данные в формате, который оптимизирует выполнение запросов. Этот механизм полезен для:
- Выполнения запросов по столбцу, который не является частью первичного ключа
- Предварительной агрегации столбцов, что снижает как вычислительные затраты, так и нагрузку на операции ввода-вывода (I/O)
Вы можете определить одну или несколько проекций для таблицы, и во время анализа запроса 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 сохраняет свое значение при слияниях и мутациях, что делает его полезным для вторичного индексирования. Это можно использовать в запросах:
Управление проекциями
Доступны следующие операции с проекциями:
ДОБАВИТЬ ПРОЕКЦИЮ
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 (включая реплицируемые варианты).