Перейти к основному содержанию
Перейти к основному содержанию

Выбор ключа партиционирования

Техника управления данными

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

В ClickHouse партиционирование организует данные в логические сегменты на основе заданного ключа. Оно задается с помощью предложения PARTITION BY при создании таблицы и обычно используется для группировки строк по временным интервалам, категориям или другим важным для бизнеса измерениям. Каждое уникальное значение выражения партиционирования формирует собственную физическую партицию на диске, и ClickHouse хранит данные в отдельных частях для каждого из этих значений. Партиционирование улучшает управление данными, упрощает политику хранения данных и может быть полезно для определенных типов запросов.

Например, рассмотрим следующую таблицу набора данных UK Price Paid с ключом партиционирования toStartOfMonth(date).

CREATE TABLE uk.uk_price_paid_simple_partitioned
(
  date Date,
  town LowCardinality(String),
  street LowCardinality(String),
  price UInt32
)
ENGINE = MergeTree
ORDER BY (town, street)
PARTITION BY toStartOfMonth(date)

Каждый раз, когда в таблицу вставляется набор строк, вместо создания (по крайней мере) одной части данных, содержащей все вставленные строки (как описано здесь), ClickHouse создаёт одну новую часть данных для каждого уникального значения ключа партиционирования среди вставленных строк:

Партиции

Сервер ClickHouse сначала разделяет строки из примерной вставки из четырёх строк, показанной на схеме выше, по их значению ключа партиционирования toStartOfMonth(date). Затем для каждой из полученных партиций строки обрабатываются как обычно, проходя через несколько последовательных шагов (① Сортировка, ② Разбиение на столбцы, ③ Сжатие, ④ Запись на диск).

Для более подробного объяснения партиционирования мы рекомендуем это руководство.

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

Партиции

Применение секционирования

Секционирование — мощный инструмент для управления большими наборами данных в ClickHouse, особенно в сценариях наблюдаемости и аналитики. Оно обеспечивает эффективные операции жизненного цикла данных, позволяя целые секции, часто выровненные по времени или бизнес-логике, удалять, переносить или архивировать одной операцией над метаданными. Это значительно быстрее и менее ресурсоёмко, чем операции удаления или копирования на уровне строк. Секционирование также органично интегрируется с возможностями ClickHouse, такими как TTL и многоуровневое хранилище, что позволяет реализовывать политики ретенции данных или стратегии горячего/холодного хранения без дополнительной оркестрации. Например, свежие данные можно хранить в быстром хранилище на базе SSD, тогда как более старые секции автоматически переносятся в более дешёвое объектное хранилище.

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

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

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

Подводя итог, пользователям в первую очередь следует рассматривать секционирование как технику управления данными. Пример управления данными см. в разделе "Managing Data" руководства по сценарию наблюдаемости и в разделе "What are table partitions used for?" документа "Core Concepts - Table partitions".

Выберите ключ партиционирования с низкой кардинальностью

Важно понимать, что большее число частей отрицательно влияет на производительность запросов. Поэтому ClickHouse будет отвечать на операции вставки ошибкой “too many parts”, если количество частей превышает заданные лимиты либо всего, либо на партицию.

Выбор правильной кардинальности для ключа партиционирования критически важен. Ключ партиционирования с высокой кардинальностью — когда число различных значений партиций велико — может привести к разрастанию количества частей данных. Поскольку ClickHouse не сливает части между партициями, слишком большое количество партиций приведёт к слишком большому количеству несведённых частей, что в итоге вызовет ошибку “Too many parts”. Слияния имеют ключевое значение для снижения фрагментации хранилища и оптимизации скорости выполнения запросов, но при партиционировании с высокой кардинальностью этот потенциал слияний теряется.

Напротив, ключ партиционирования с низкой кардинальностью — с количеством различных значений менее 100–1 000 — обычно является оптимальным. Он обеспечивает эффективное слияние частей, удерживает накладные расходы на метаданные на низком уровне и предотвращает чрезмерное создание объектов в хранилище. Кроме того, ClickHouse автоматически строит индексы MinMax по столбцам партиционирования, что может существенно ускорить запросы, фильтрующие по этим столбцам. Например, фильтрация по месяцу, когда таблица партиционирована по toStartOfMonth(date), позволяет движку полностью пропускать нерелевантные партиции и их части.

Хотя партиционирование может улучшить производительность для некоторых типов запросов, по своей сути это механизм управления данными. Во многих случаях выполнение запросов по всем партициям может быть медленнее, чем работа с непартиционированной таблицей, из‑за повышенной фрагментации данных и большего числа просканированных частей. Используйте партиционирование взвешенно и всегда убедитесь, что выбранный ключ имеет низкую кардинальность и соответствует политикам жизненного цикла данных (например, политике удержания через TTL). Если вы не уверены, что партиционирование необходимо, можно начать без него и оптимизировать схему позже на основе наблюдаемых паттернов доступа.