Ускорение аналитики с помощью MergeTree
В предыдущем разделе вы подключили ClickHouse к каталогу данных и выполняли запросы к открытым табличным форматам напрямую. Хотя выполнять запросы к данным на месте удобно, форматы lakehouse не оптимизированы для рабочих нагрузок с низкой задержкой и высокой степенью параллелизма, характерных для дашбордов и операционной отчетности. Для таких сценариев загрузка данных в движок ClickHouse MergeTree обеспечивает значительно более высокую производительность.
MergeTree имеет несколько преимуществ по сравнению с прямым чтением открытых табличных форматов:
- Разреженный первичный индекс — упорядочивает данные на диске по выбранному ключу, позволяя ClickHouse пропускать большие диапазоны нерелевантных строк при выполнении запросов.
- Расширенные типы данных — нативная поддержка таких типов, как JSON, LowCardinality и Enum, обеспечивает более компактное хранение и более быструю обработку.
- Индексы пропуска и полнотекстовые индексы — структуры вторичных индексов, которые позволяют ClickHouse пропускать гранулы, не соответствующие предикатам фильтрации в запросе; особенно эффективны для нагрузок, связанных с текстовым поиском.
- Быстрые вставки с автоматической компакцией — ClickHouse рассчитан на вставки с высокой пропускной способностью и автоматически объединяет части данных в фоновом режиме, аналогично компакции в открытых табличных форматах.
- Оптимизировано для параллельного чтения — столбцовая структура хранения MergeTree в сочетании с несколькими уровнями кэширования поддерживает аналитические нагрузки в реальном времени с высокой степенью параллелизма — то, для чего открытые табличные форматы не предназначены.
В этом руководстве показано, как загружать данные из каталога в таблицу MergeTree с помощью INSERT INTO SELECT, чтобы ускорить аналитику.
Подключение к каталогу
Мы будем использовать то же подключение к Unity Catalog из предыдущего руководства, через конечную точку Iceberg REST:
Просмотр списка таблиц
Изучите схему
Эта таблица содержит ~283 миллиона строк логов из прогонов тестов ClickHouse CI — реалистичный набор данных для анализа производительности.
Запрос к таблице lakehouse
Выполним запрос, который отфильтровывает логи по имени потока и типу экземпляра, ищет ошибки в тексте сообщения и группирует результаты по логгеру:
Запрос занимает почти 9 секунд, потому что ClickHouse должен выполнить полное сканирование таблицы по всем файлам Parquet в Объектном хранилище. Производительность можно повысить с помощью партиционирования, но у столбцов вроде logger_name кардинальность может быть слишком высокой для эффективного партиционирования. У нас также нет индексов, таких как текстовые индексы, чтобы дополнительно отсекать данные. Именно здесь 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 в Объектном хранилище.