Что такое партиции таблицы в ClickHouse?
Партиции объединяют части данных таблицы из семейства движков MergeTree в упорядоченные логические единицы. Это способ организации данных в соответствии с определёнными критериями, такими как временные диапазоны, категории или другие ключевые атрибуты. Такие логические единицы упрощают управление данными, выполнение запросов и оптимизацию.
PARTITION BY
PARTITION BY toStartOfMonth(date), которая распределяет части таблицы по месяцам продажи недвижимости:
Структура на диске
Сначала сервер ClickHouse разделяет строки из примера вставки с 4 строками, схематично показанного на диаграмме выше, по значению ключа партиционирования
toStartOfMonth(date).
Затем для каждой выявленной партиции строки обрабатываются как обычно в несколько последовательных шагов (① Сортировка, ② Разбиение на столбцы, ③ Сжатие, ④ Запись на диск).
Обратите внимание: при включенном партиционировании ClickHouse автоматически создает индексы MinMax для каждой части данных. Это просто файлы для каждого столбца таблицы, используемого в выражении ключа партиционирования, которые содержат минимальное и максимальное значения этого столбца в пределах части данных.
Слияния внутри партиций
Как показано на диаграмме выше, части, принадлежащие разным партициям, никогда не сливаются. Если выбран ключ партиционирования с высокой мощностью, то части, распределенные по тысячам партиций, никогда не будут кандидатами на слияние, что приведет к превышению заранее заданных ограничений и вызовет пресловутую ошибку
Too many parts. Решение этой проблемы простое: выберите разумный ключ партиционирования с мощностью менее 1000..10000.
Мониторинг партиций
_partition_value:
Кроме того, ClickHouse отслеживает все части и партиции всех таблиц в системной таблице system.parts, а следующий запрос возвращает для приведённой выше тестовой таблицы список всех партиций, а также текущее количество активных частей и суммарное число строк в этих частях для каждой партиции:
Для чего нужны партиции таблиц?
Управление данными
toStartOfMonth(date), целые партиции (наборы частей таблицы), подпадающие под условие TTL, будут удаляться, что повышает эффективность очистки без переписывания частей.
Аналогично, вместо удаления старых данных их можно автоматически и эффективно перемещать на более экономичный уровень хранилища:
Оптимизация запросов
date), который входит в ключ партиционирования таблицы, так и по столбцу (town), который входит в первичный ключ таблицы (при этом date не является частью первичного ключа).
ClickHouse обрабатывает этот запрос, применяя последовательность методов отсеивания данных, чтобы не обрабатывать нерелевантные данные:
① Отсечение партиций: MinMax indexes используются, чтобы игнорировать целые партиции (наборы частей), которые заведомо не могут соответствовать фильтру запроса по столбцам, используемым в ключе партиционирования таблицы. ② Отсечение гранул: Для оставшихся частей данных после шага ① используется их первичный индекс, чтобы игнорировать все гранулы (блоки строк), которые заведомо не могут соответствовать фильтру запроса по столбцам, используемым в первичном ключе таблицы. Мы можем увидеть эти шаги отсеивания данных, изучив физический план выполнения для нашего примера запроса выше с помощью оператора EXPLAIN :
date, чтобы выявить 11 из 3257 существующих гранул (блоков строк), хранящихся в 1 из 436 существующих активных частей данных, которые содержат строки, соответствующие фильтру date в запросе.
② Отсечение гранул: строки 19–24 приведённого выше вывода EXPLAIN показывают, что затем ClickHouse использует первичный индекс (созданный по полю town) части данных, определённой на шаге ①, чтобы ещё сильнее сократить число гранул (содержащих строки, которые потенциально также соответствуют фильтру town в запросе) — с 11 до 1. Это также отражено в выводе ClickHouse-client, который мы привели выше для выполненного запроса:
Партиционирование — это прежде всего средство управления данными
uk_price_paid_simple_partitioned имеет более 600 партиций и, следовательно, 600 306 активных частей данных. В то же время в таблице без партиционирования uk_price_paid_simple все исходные части данных могли быть объединены фоновыми слияниями в одну активную часть.
Если посмотреть физический план выполнения нашего запроса из примера выше без фильтра по партиции для партиционированной таблицы с помощью оператора EXPLAIN, то в строках 19 и 20 приведенного ниже вывода видно, что ClickHouse определил 671 из 3257 существующих гранул (блоков строк), распределенных по 431 из 436 существующих активных частей данных, которые потенциально содержат строки, соответствующие фильтру запроса, и поэтому будут просканированы и обработаны движком запросов: