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

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

примечание

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

Никогда не используйте слишком детализированное партиционирование. Не разбивайте данные по идентификаторам клиентов или именам. Вместо этого сделайте идентификатор клиента или имя первой колонкой в выражении ORDER BY.

Партиционирование доступно для таблиц семейства MergeTree, включая реплицированные таблицы и материализованные представления.

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

Партиция указывается в клаузе PARTITION BY expr при создании таблицы. Ключ партиционирования может быть любым выражением из колонок таблицы. Например, чтобы указать партиционирование по месяцу, используйте выражение toYYYYMM(date_column):

Ключ партиционирования также может быть кортежем выражений (аналогично первичному ключу). Например:

В этом примере мы устанавливаем партиционирование по типам событий, которые произошли на текущей неделе.

По умолчанию партиция с плавающей запятой не поддерживается. Чтобы использовать её, включите настройку allow_floating_point_partition_key.

При вставке новых данных в таблицу эти данные сохраняются как отдельная часть (чанк), отсортированная по первичному ключу. Через 10-15 минут после вставки части одной и той же партиции сливаются в целую часть.

к сведению

Слияние работает только для частей данных, которые имеют одинаковое значение для выражения партиционирования. Это означает, что вы не должны делать чрезмерно детализированные партиции (более чем около тысячи партиций). В противном случае запрос SELECT будет работать плохо из-за неоправданно большого количества файлов в файловой системе и открытых дескрипторов файлов.

Используйте таблицу system.parts, чтобы просмотреть части таблицы и партиции. Например, предположим, что у нас есть таблица visits с партиционированием по месяцам. Выполним запрос SELECT для таблицы system.parts:

Столбец partition содержит названия партиций. В этом примере две партиции: 201901 и 201902. Вы можете использовать это значение столбца, чтобы указать имя партиции в запросах ALTER ... PARTITION.

Столбец name содержит названия частей данных партиции. Вы можете использовать это значение столбца, чтобы указать имя части в запросе ALTER ATTACH PART.

Рассмотрим название части: 201901_1_9_2_11:

  • 201901 — это имя партиции.
  • 1 — минимальный номер блока данных.
  • 9 — максимальный номер блока данных.
  • 2 — уровень чанка (глубина дерева слияния, из которого он сформирован).
  • 11 — версия мутации (если часть была мутирована)
к сведению

Части таблиц старого типа имеют название: 20190117_20190123_2_2_0 (минимальная дата - максимальная дата - минимальный номер блока - максимальный номер блока - уровень).

Столбец active показывает статус части. 1 — активная; 0 — неактивная. Неактивные части, например, это исходные части, остающиеся после слияния в более крупную часть. Коррупционные части данных также обозначаются как неактивные.

Как видно из примера, есть несколько разделенных частей одной и той же партиции (например, 201901_1_3_1 и 201901_1_9_2). Это означает, что эти части еще не были объединены. ClickHouse периодически объединяет вставленные части данных, примерно через 15 минут после вставки. Кроме того, вы можете выполнить несогласованное слияние, используя запрос OPTIMIZE. Пример:

Неактивные части будут удалены примерно через 10 минут после слияния.

Еще один способ просмотра набора частей и партиций — зайти в директорию таблицы: /var/lib/clickhouse/data/<database>/<table>/. Например:

Папки '201901_1_1_0', '201901_1_7_1' и так далее представляют собой директории частей. Каждая часть относится к соответствующей партиции и содержит данные только за определенный месяц (таблица в этом примере имеет партиционирование по месяцам).

Директория detached содержит части, которые были отсоединены от таблицы с использованием запроса DETACH. Поврежденные части также перемещаются в эту директорию вместо того, чтобы быть удаленными. Сервер не использует части из директории detached. Вы можете добавлять, удалять или изменять данные в этой директории в любое время — сервер не узнает об этом, пока вы не выполните запрос ATTACH.

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

ClickHouse позволяет вам выполнять операции с партициями: удалять их, копировать из одной таблицы в другую или создавать резервные копии. См. список всех операций в разделе Манипуляции с партициями и частями.

Оптимизация Group By с использованием ключа партиционирования

Для некоторых комбинаций ключа партиционирования таблицы и ключа GROUP BY запроса может быть возможно выполнять агрегацию для каждой партиции независимо. Тогда нам не придется объединять частично агрегированные данные из всех потоков выполнения в конце, поскольку мы обеспечили гарантию, что каждое значение ключа GROUP BY не может появиться в рабочих наборах двух разных потоков.

Типичный пример:

примечание

Производительность такого запроса сильно зависит от структуры таблицы. Поэтому оптимизация не включена по умолчанию.

Ключевые факторы для хорошей производительности:

  • количество партиций, участвующих в запросе, должно быть достаточно большим (более max_threads / 2), в противном случае запрос будет недоиспользовать ресурсы машины
  • партиции не должны быть слишком маленькими, чтобы пакетная обработка не превращалась в построчную
  • партиции должны быть сопоставимы по размеру, чтобы все потоки выполняли примерно одно и то же количество работы
к сведению

Рекомендуется применять какую-нибудь хеш-функцию к колонкам в клаузе partition by, чтобы равномерно распределить данные между партициями.

Соответствующие настройки:

  • allow_aggregate_partitions_independently - контролирует, включена ли оптимизация
  • force_aggregate_partitions_independently - принудительно включает её использование, когда это применимо с точки зрения корректности, но внутренней логикой, которая оценивает её целесообразность, отключается
  • max_number_of_partitions_for_independent_aggregation - жесткий лимит на максимальное количество партиций, которое может иметь таблица