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

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

примечание

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

Никогда не используйте слишком детализированное партиционирование. Не партиционируйте ваши данные по идентификаторам клиентов или именам. Вместо этого сделайте идентификатор клиента или имя первой колонкой в выражении 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 — жесткое ограничение на максимальное количество партиций, которое может иметь таблица