Оптимальная сортировка таблиц Clickhouse: улучшения ORDER BY в релизе 24.6

таблицы индексы сортировка ClickHouse, курсы ClickHouse для дата-инженера, инженерия данных примеры курсы обучение, DWH ClickHouse, Школа Больших Данных Учебный Центр Коммерсант

Зачем в ClickHouse 24.6 добавлена настройка optimize_row_order для оптимизации порядка строк MergeTree-таблиц, как она работает и где ее применять.

Как связаны индексация и сортировка таблиц в ClickHouse

Даже не будучи классической реляционной СУБД, ClickHouse поддерживает индексацию, насколько это возможно в его колоночной природе, индексируя первичным ключом целую группу строк (гранулу) в таблице из частей данных, отсортированных по первичному ключу. Подробнее об этом мы писали здесь. Физический порядок строк на диске в таблицах основного движка MergeTree определяется их ключом сортировки, указанном в операторе ORDER BY. Оператор ORDER BY и связанный с ней физический порядок строк используются для создания разреженного индекса в диапазонных запросов и определения ключ для режимов слияния, например, таблиц Aggregating- или ReplacingMergeTree. Также физический порядок строк обеспечивает улучшенное сжатие данных путем их совместного размещения в файлах столбцов. Это особенно важно при работе с огромными объемами данных, для чего изначально и создавался ClickHouse.

Чтобы сжимать данные еще более эффективно, для обычных MergeTree-таблиц в релизе 24.6, выпущенном в начале июля 2024 года, добавлен новый параметр optimize_row_order. После сортировки по столбцам с помощью ORDER BY он автоматически сортирует строки таблицы во время приема данных по оставшимся столбцам на основе их мощности, обеспечивая оптимальное сжатие. Популярные кодеки сжатия, такие как LZ4 и ZSTD достигают максимальных показателей, если данные имеют закономерность, например, длинные последовательности (серии) одинаковых значений в каждом столбце. Оптимизация достигается благодаря физическому хранению строк, отсортированных по значениям столбцов, начиная со столбцов с наименьшей кардинальностью. Для диапазона строк с одинаковыми значениями столбцов ORDER BY строки сортируются по значениям оставшихся столбцов, упорядоченных по диапазону и локальному количеству столбцов в порядке возрастания. Раньше, при упорядочивании строк по значениям столбцов с высокой кардинальностью, их было невозможно сортировать на основе значений других столбцов для создания длинных серий одинаковых значений, что приводило к низкому коэффициенту сжатия файлов столбцов. Изменения в ClickHouse 24.6 устраняют эту проблему: параметр optimize_row_order улучшает сжатие данных при вставке в таблицы движка MergeTree. Как это работает, посмотрим далее.

Настройка optimize_row_order в релизе 24.6

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

Как уже было отмечено выше, эта настройка подходит для таблиц без первичных ключей или с первичными ключами с небольшим числом уникальных значений. Если первичный ключ имеет много уникальных значений, например, временные метки, особого смысла от этой настройки не будет. Также настройка подойдет для обычных MergeTree-таблиц с ключом ORDER BY с низкой кардинальностью, т.е. с несколькими различными значениями ключа сортировки.

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

CREATE TABLE user_events
(
    UserID UInt32,
    URL String,
    Event  String,
    EventTime DateTime
)
ENGINE = MergeTree
PRIMARY KEY (UserID, URL)
ORDER BY (UserID, URL, EventTime)
SETTINGS optimize_row_order = 1;

В этой таблице комплексный первичный ключ состоит из двух столбцов: идентификатора пользователя UserID и URL веб-страницы. Данные в таблице будут отсортированы по столбцам UserID, URL и EventTime. Это означает, что записи будут физически располагаться в указанном порядке, что ускоряет выполнение запросов фильтрации или сортировки по этим столбцам. Настройка optimize_row_order = 1 включает оптимизацию порядка строк: ClickHouse пытается переставить строки так, чтобы одинаковые значения шли подряд, что улучшает сжимаемость. В этом примере одинаковые значения будут часто встречаться в столбцах UserID, URL и  Event. Поэтому включение оптимизации порядка строк при создании таблицы с событиями пользовательского поведения отлично подходит для сценариев фильтрации и поиска событий пользователей с учетом хронологического порядка.

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

Бенчмаркинговые тесты показали, что сжатие данных с новой настройкой улучшается примерно на 30%. Однако, включение optimize_row_order добавляет дополнительные затраты на процесс вставки данных, увеличивая время вставки на 30-50%, но улучшает показатели сжатия на 20-40%. О том, какие новые возможности представлены в следующем релизе этой колоночной СУБД, читайте в нашей статье про ClickHouse 24.7.

Освойте использование ClickHouse для аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Источники

  1. https://clickhouse.com/blog/clickhouse-release-24-06
  2. https://clickhouse.com/docs/en/operations/settings/merge-tree-settings#optimize_row_order
Я даю свое согласие на обработку персональных данных и соглашаюсь с политикой конфиденциальности.
Поиск по сайту