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

Части таблицы

Что такое части таблицы в ClickHouse?


Данные каждой таблицы в семействе движков таблиц ClickHouse MergeTree организованы на диске как набор неизменяемых частей данных (data parts).

Чтобы проиллюстрировать это, мы используем эту таблицу (адаптированную из набора данных о ценах на недвижимость в Великобритании), в которой фиксируются дата, город, улица и цена по проданным объектам недвижимости в Соединенном Королевстве:

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

Вы можете выполнить запрос к этой таблице в нашем ClickHouse SQL Playground.

Часть (data part) создаётся каждый раз, когда в таблицу вставляется набор строк. Следующая диаграмма иллюстрирует это:


Когда сервер ClickHouse обрабатывает пример вставки с 4 строками (например, через оператор INSERT INTO), показанный на диаграмме выше, он выполняет несколько шагов:

Сортировка: Строки сортируются по ^^ключу сортировки^^ таблицы (town, street), а для отсортированных строк генерируется разреженный первичный индекс.

Разделение: Отсортированные данные разделяются на столбцы.

Сжатие: Каждый столбец сжимается.

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

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

Части ^^данных^^ являются самодостаточными и включают все метаданные, необходимые для интерпретации их содержимого без обращения к центральному каталогу. Помимо разреженного первичного индекса, ^^части^^ содержат дополнительные метаданные, такие как вторичные индексы пропуска данных, статистика столбцов, контрольные суммы, min-max индексы (если используется partitioning) и другое.

Слияния частей

Чтобы управлять числом ^^parts^^ в таблице, фоновый процесс background merge периодически объединяет меньшие ^^parts^^ в более крупные до тех пор, пока они не достигнут настраиваемого сжатого размера (обычно около 150 ГБ). Слитые ^^parts^^ помечаются как неактивные и удаляются по истечении настраиваемого временного интервала. Со временем этот процесс создаёт иерархическую структуру слитых ^^parts^^, поэтому таблица и называется ^^MergeTree^^:


Чтобы минимизировать количество исходных ^^parts^^ и накладные расходы на слияния, клиентским приложениям базы данных рекомендуется либо выполнять пакетные вставки данных, например по 20 000 строк за раз, либо использовать режим асинхронной вставки, при котором ClickHouse буферизует строки из нескольких входящих операторов INSERT в одну и ту же таблицу и создаёт новую ^^part^^ только после того, как размер буфера превысит настраиваемый порог или истечёт таймаут.

Мониторинг частей таблицы

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

SELECT _part
FROM uk.uk_price_paid_simple
GROUP BY _part
ORDER BY _part ASC;

   ┌─_part───────┐
1. │ all_0_5_1   │
2. │ all_12_17_1 │
3. │ all_18_23_1 │
4. │ all_6_11_1  │
   └─────────────┘

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

Кроме того, ClickHouse ведёт учёт информации обо всех ^^частях^^ всех таблиц в системной таблице system.parts, и следующий запрос для нашей таблицы из примера выше возвращает список всех текущих активных ^^частей^^, их уровень слияния и количество строк, хранящихся в этих ^^частях^^:

SELECT
    name,
    level,
    rows
FROM system.parts
WHERE (database = 'uk') AND (`table` = 'uk_price_paid_simple') AND active
ORDER BY name ASC;

   ┌─name────────┬─level─┬────rows─┐
1. │ all_0_5_1   │     1 │ 6368414 │
2. │ all_12_17_1 │     1 │ 6442494 │
3. │ all_18_23_1 │     1 │ 5977762 │
4. │ all_6_11_1  │     1 │ 6459763 │
   └─────────────┴───────┴─────────┘

Уровень слияния увеличивается на единицу при каждом дополнительном слиянии этой части. Уровень 0 означает, что это новая часть, которая ещё ни разу не сливалась.