Перейти к основному содержанию
Одной из ключевых причин высокой производительности запросов в ClickHouse является эффективное сжатие данных. Чем меньше данных хранится на диске, тем быстрее выполняются запросы и вставки за счёт снижения накладных расходов на I/O. Столбцовая архитектура ClickHouse естественным образом располагает схожие данные рядом, что позволяет алгоритмам сжатия и кодекам значительно уменьшать их объём. Чтобы максимально использовать преимущества сжатия, важно тщательно подбирать подходящие типы данных. Эффективность сжатия в ClickHouse в основном зависит от трёх факторов: ключа сортировки, типов данных и кодеков — все они задаются схемой таблицы. Выбор оптимальных типов данных сразу улучшает как эффективность хранилища, так и производительность запросов. Несколько простых рекомендаций могут значительно улучшить схему:
  • Используйте строгие типы: Всегда выбирайте для столбцов правильный тип данных. Для числовых полей и полей с датой следует использовать соответствующие числовые типы и типы даты, а не универсальные типы String. Это обеспечивает корректную семантику для фильтрации и агрегаций.
  • Избегайте столбцов типа Nullable: Столбцы с типом Nullable создают дополнительную нагрузку, поскольку требуют хранения отдельных столбцов для отслеживания null-значений. Используйте Nullable только тогда, когда действительно необходимо различать пустое значение и null. В остальных случаях обычно достаточно значений по умолчанию или их нулевых эквивалентов. Дополнительную информацию о том, почему этого типа следует избегать без необходимости, см. в разделе Избегайте столбцов типа Nullable.
  • Минимизируйте числовую точность: Выбирайте числовые типы с минимальной разрядностью, которая при этом покрывает ожидаемый диапазон данных. Например, лучше использовать UInt16 вместо Int32, если отрицательные значения не нужны и диапазон укладывается в 0–65535.
  • Оптимизируйте точность даты и времени: Выбирайте наиболее грубый тип даты или времени, который соответствует требованиям запросов. Для полей, содержащих только дату, используйте Date или Date32, а DateTime предпочитайте DateTime64, если только не требуется точность до миллисекунд или выше.
  • Используйте LowCardinality и специализированные типы: Для столбцов, содержащих менее чем примерно 10 000 уникальных значений, используйте типы LowCardinality, чтобы существенно сократить объём хранилища за счёт кодирования с использованием словаря. Аналогично, FixedString следует использовать только тогда, когда значения в столбце действительно представляют собой строки фиксированной длины (например, коды стран или валют), а для столбцов с конечным набором возможных значений предпочтительнее типы Enum, поскольку они обеспечивают эффективное хранение и встроенную проверку данных.
  • Enum для валидации данных: Тип Enum можно использовать для эффективного кодирования перечислимых значений. Enum может быть 8- или 16-битным в зависимости от количества уникальных значений, которые нужно хранить. Рассмотрите этот вариант, если вам нужна проверка во время вставки (необъявленные значения будут отклонены) или если вы хотите выполнять запросы, использующие естественный порядок значений Enum; например, представьте столбец feedback, содержащий ответы пользователей Enum(’:(’ = 1, ’:|’ = 2, ’:)’ = 3).

Пример

ClickHouse предлагает встроенные инструменты, упрощающие оптимизацию типов. Например, определение схемы может автоматически выявить исходные типы. Рассмотрим набор данных Stack Overflow, общедоступный в формате Parquet. Простой запуск определения схемы с помощью команды DESCRIBE позволяет получить исходную неоптимизированную схему.
По умолчанию ClickHouse сопоставляет их с эквивалентными типами Nullable. Это предпочтительно, поскольку схема строится только на основе выборки строк.
Обратите внимание: ниже мы используем glob pattern *.parquet, чтобы прочитать все файлы в папке stackoverflow/parquet/posts.
Применив наши простые правила на раннем этапе к таблице posts, мы можем определить оптимальный тип для каждого столбца:
СоветПри выборе типа для столбца важно учитывать его числовой диапазон и количество уникальных значений. Чтобы определить диапазон значений для всех столбцов и число уникальных значений, можно использовать простой запрос SELECT * APPLY min, * APPLY max, * APPLY uniq FROM table FORMAT Vertical. Рекомендуем выполнять его на меньшем подмножестве данных, так как эта операция может быть затратной.
Это даёт следующую оптимизированную схему (с точки зрения типов):

Избегайте столбцов типа Nullable

Nullable столбец (например, Nullable(String)) создаёт отдельный столбец типа UInt8. Этот дополнительный столбец приходится обрабатывать каждый раз при работе со столбцом Nullable. Это требует дополнительного места в хранилище и почти всегда отрицательно сказывается на производительности. Чтобы избежать столбцов Nullable, задайте для этого столбца значение по умолчанию. Например, вместо:
используйте
Учитывайте свой сценарий использования; значение по умолчанию может быть неподходящим.
Последнее изменение 2 июля 2026 г.