ADG Оставить заявку
Блог Данные и аналитика 4 мин чтения

ClickHouse 23.3 LTS: тестируем новый query optimizer перед апгрейдом аналитического кластера

Переходим на ClickHouse 23.3 LTS: новый query optimizer дал 30-40% ускорения на сложных агрегациях без изменений запросов. Как мы тестировали производительность до апгрейда.

Контекст момента

Выход ClickHouse 23.3 LTS с новым оптимизатором запросов и улучшенными materialized views

ClickHouse 23.3 получил статус LTS в апреле. Для нас это сигнал: LTS-ветка означает, что можно планировать миграцию продакшн-кластеров, не чувствуя себя альфа-тестером. Главное в этом релизе - переработанный query optimizer и обновлённая механика materialized views. Разбираемся, что это даёт на практике и как не прострелить себе ногу при апгрейде.

Что поменялось в оптимизаторе

До 23.3 ClickHouse использовал достаточно консервативный планировщик: JOIN-ы, подзапросы и цепочки агрегаций планировались с минимумом трансформаций. Новый оптимизатор включает cost-based эвристики для переупорядочивания JOIN-ов, проталкивания предикатов вглубь подзапросов и элиминации избыточных агрегаций. Важно: он включён по умолчанию, но управляется флагом allow_experimental_analyzer. В 23.3 это уже не экспериментально в полном смысле - команда ClickHouse считает его production-ready, хотя «экспериментальный» в названии флага сохранился как артефакт.

На наших тестовых запросах - многоуровневые агрегации по событиям с несколькими JOIN-ами на словари - разница оказалась заметной. Сложные аналитические запросы с GROUP BY по нескольким измерениям ускорились в районе 30-40%. Простые точечные выборки - без изменений, что логично: там нечего оптимизировать.

Главная приятность: запросы переписывать не нужно. Оптимизатор работает на уровне плана, SQL остаётся прежним.

Materialized views: что изменилось

Materialized views в ClickHouse всегда были немного своеобразны - они работают как триггеры на INSERT, а не как настоящие материализованные представления в духе PostgreSQL. В 23.3 несколько улучшений:

  • Улучшенная обработка ошибок - при падении INSERT в целевую таблицу materialized view теперь лучше откатывает состояние, меньше шансов получить рассинхронизированные данные.
  • Производительность цепочек - если materialized view ссылается на другой materialized view, планировщик стал лучше раскрывать эти цепочки.

Как мы тестировали производительность перед апгрейдом

Апгрейдить продакшн-кластер «вслепую», полагаясь только на changelog - не наш стиль. Схема тестирования, которую мы применяем в рамках DWH и BI-сопровождения:

Первое - зеркальный стенд. Разворачиваем кластер целевой версии с той же топологией (количество шардов/реплик), копируем схему. Данные - либо полный снапшот за последний месяц, либо репрезентативная выборка. Ключевой момент: схема должна быть идентична продакшн вплоть до настроек MergeTree - иначе сравнение некорректно.

Второе - реплей запросов. Собираем лог реальных запросов из system.query_log за типичные сутки. Фильтруем: убираем DDL, системные запросы, запросы с ошибками. Остаётся несколько сотен уникальных шаблонов запросов. Прогоняем их на обоих кластерах с одинаковыми параметрами, фиксируем query_duration_ms и read_rows.

Третье - сравнение планов. Для запросов, которые показали значительное расхождение (в любую сторону - ускорение или замедление), смотрим EXPLAIN на обоих кластерах. Это помогает понять, что именно поменял оптимизатор. Несколько запросов с нестандартными паттернами JOIN-ов на тесте дали регрессию - порядка 15-20% замедления. Причина оказалась в том, что оптимизатор выбирал не тот порядок JOIN-ов для специфичных кардинальностей. Для таких запросов добавили хинт SETTINGS join_algorithm = 'hash' - проблема ушла.

Четвёртое - тест materialized views. Отдельно гоняем INSERT-нагрузку через clickhouse-benchmark с реальными батчами данных. Смотрим на латентность INSERT и на то, не растёт ли очередь в system.merges. Если materialized view не успевает за потоком - это проблема, которую лучше увидеть на стенде, а не в продакшне в пятницу вечером.

Что нашли неожиданного

Один момент, который не был очевиден из changelog: новый анализатор по-другому разворачивает некоторые CTE. Запросы с WITH ... AS (SELECT ...) в нескольких местах начали выполнять подзапрос несколько раз вместо одного - что логически эквивалентно, но по производительности хуже. Временное решение - материализовать CTE через временную таблицу или переписать в подзапрос без CTE. Зафиксировали как known issue, команда ClickHouse в курсе.

Итог на сегодня

Тесты закончены, аномалии задокументированы. Апгрейд запланирован на следующую неделю по схеме rolling update - сначала реплики, затем шарды. Общий вывод: 23.3 LTS выглядит как хороший релиз для продакшна, прирост на аналитических запросах реальный. Главное - не пропускать этап тестирования с реальными запросами: changelog пишут о среднем случае, у вас может быть свой.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.