Ускорение аналитики с помощью MergeTree
В предыдущем разделе вы подключили ClickHouse к каталогу данных и выполняли запросы к открытым табличным форматам напрямую. Хотя выполнять запросы к данным по месту их хранения удобно, lakehouse-форматы не оптимизированы для низких задержек и высокой параллельности, которые требуются дашбордам и операционной отчётности. Для таких сценариев загрузка данных в движок MergeTree ClickHouse обеспечивает существенно более высокую производительность.
MergeTree предоставляет несколько преимуществ по сравнению с прямым чтением открытых табличных форматов:
- Разреженный первичный индекс — упорядочивает данные на диске по выбранному ключу, позволяя ClickHouse пропускать большие диапазоны нерелевантных строк во время выполнения запросов.
- Расширенные типы данных — нативная поддержка типов, таких как JSON, LowCardinality и Enum, что обеспечивает более компактное хранение и более быструю обработку.
- Пропускающие индексы и полнотекстовые индексы — вторичные структуры индексов, которые позволяют ClickHouse пропускать гранулы, не соответствующие фильтрам запроса, что особенно эффективно для нагрузок полнотекстового поиска.
- Быстрые вставки с автоматической компакцией — ClickHouse спроектирован для высокопроизводительных вставок и автоматически объединяет части данных в фоновом режиме, аналогично операции compaction в открытых табличных форматах.
- Оптимизация для одновременных чтений — столбцовая организация хранения MergeTree в сочетании с несколькими уровнями кеширования поддерживает аналитические рабочие нагрузки в реальном времени с высокой степенью параллельности — то, для чего открытые табличные форматы не предназначены.
В этом руководстве показано, как загружать данные из каталога в таблицу MergeTree с помощью INSERT INTO SELECT для более быстрой аналитики.
Подключение к каталогу
Мы будем использовать то же подключение к Unity Catalog из предыдущего руководства, подключаясь через REST-эндпоинт Iceberg:
Список таблиц
Изучите схему таблицы
Эта таблица содержит около 283 миллионов строк логов из прогонов CI-тестов ClickHouse — реалистичный набор данных для оценки аналитической производительности.
Выполнение запроса по таблице lakehouse
Выполним запрос, который отфильтрует логи по имени потока и типу инстанса, найдёт в тексте сообщения ошибки и сгруппирует результаты по логгеру:
Запрос выполняется почти 9 секунд, потому что ClickHouse должен выполнить полное сканирование всей таблицы по всем файлам Parquet в Объектном хранилище. Производительность можно улучшить с помощью партиционирования, но такие столбцы, как logger_name, могут иметь слишком высокую кардинальность, чтобы их можно было эффективно использовать для партиционирования. У нас также нет индексов, таких как Text indices, чтобы дополнительно отфильтровывать данные. В этом и заключается преимущество MergeTree.
Загрузка данных в MergeTree
Создайте оптимизированную таблицу
Мы создаём таблицу MergeTree с некоторыми оптимизациями схемы. Обратите внимание на несколько ключевых отличий от схемы Iceberg:
- Без обёрток
Nullable— удалениеNullableповышает эффективность хранения и производительность выполнения запросов. LowCardinality(String)на столбцахlevel,instance_type,thread_nameиcheck_name— выполняет словарное кодирование столбца с небольшим числом различных значений для лучшего сжатия и более быстрой фильтрации.- Полнотекстовый индекс на столбце
message— ускоряет текстовый поиск по токенам, напримерhasToken(message, 'error'). - Ключ
ORDER BYвида(instance_type, thread_name, toStartOfMinute(event_time))— выравнивает данные на диске с распространёнными шаблонами фильтрации, чтобы разреженный первичный индекс мог пропускать нерелевантные гранулы.
Вставка данных из каталога
Используйте INSERT INTO SELECT, чтобы загрузить ~300 млн строк из таблицы lakehouse в нашу таблицу ClickHouse:
Повторное выполнение запроса
Если теперь повторно выполнить тот же запрос по таблице MergeTree, мы увидим, что производительность значительно улучшится:
Тот же запрос теперь выполняется за 0,22 секунды — это примерно 40-кратное ускорение. Два ключевых улучшения обеспечивают этот прирост производительности:
- Разреженный первичный индекс — ключ
ORDER BY (instance_type, thread_name, ...)позволяет ClickHouse сразу переходить к гранулам, соответствующимinstance_type = 'm6i.4xlarge'иthread_name = 'TCPHandler', сокращая число обрабатываемых строк с 283 миллионов до всего лишь 14 миллионов. - Полнотекстовый индекс — индекс
text_idxпо столбцуmessageпозволяет функцииhasToken(message, 'error')выполняться по индексу, а не путём сканирования каждой строковой записи сообщения, ещё больше снижая объём данных, который нужно прочитать ClickHouse.
В результате запрос без проблем может обеспечивать работу дашборда в реальном времени — на масштабах и с задержками, недостижимыми при выполнении запросов к файлам Parquet в объектном хранилище.