New Analyzer (default 24.3+)
С версии 24.3 ClickHouse использует новый анализатор запросов по умолчанию. Анализатор — это первый этап обработки запроса: он разбирает SQL, проверяет корректность, выводит типы и готовит план для оптимизатора. Новый анализатор делает это лучше старого, но вводит breaking changes, которые могут сломать существующие запросы.
Настройка enable_analyzer
Новый анализатор контролируется настройкой enable_analyzer:
-- Проверить текущее состояние
SELECT name, value FROM system.settings WHERE name = 'enable_analyzer';
-- Принудительно включить (default с 24.3)
SET enable_analyzer = 1;
-- Откатиться на старый анализатор
SET enable_analyzer = 0;
На production-кластерах рекомендуется тестировать запросы с enable_analyzer = 1 перед обновлением до 24.3+.
Улучшения нового анализатора
1. Ранняя валидация
Старый анализатор проверял корректность запроса после оптимизации. Ошибки обнаруживались поздно, а сообщения были неинформативными.
Новый анализатор проверяет запрос до оптимизации:
-- Старый анализатор: ошибка на этапе выполнения
-- Новый анализатор: ошибка сразу при анализе
SELECT user_id, count()
FROM events
GROUP BY country;
-- Ошибка: user_id не в GROUP BY и не обёрнут в агрегатную функцию
Результат: более понятные сообщения об ошибках и более быстрый цикл отладки.
2. Вывод типов
Новый анализатор выводит типы выражений на этапе анализа, а не на этапе выполнения. Это позволяет:
- Обнаруживать несовместимость типов до начала чтения данных
- Применять более точные оптимизации на основе известных типов
- Генерировать корректный код для JIT-компиляции
-- Новый анализатор знает тип результата до выполнения
SELECT toDate('2024-01-15') + INTERVAL 1 MONTH;
-- Тип результата: Date (определён при анализе, не при выполнении)
3. Консистентное поведение JOINs
Старый анализатор мог давать разные результаты для эквивалентных запросов с JOIN. Новый анализатор гарантирует консистентное поведение:
- Детерминированный порядок разрешения столбцов
- Одинаковые результаты для RIGHT JOIN и эквивалентного LEFT JOIN (с переставленными таблицами)
- Корректная обработка Nullable столбцов из OUTER JOIN
4. Улучшенные оптимизации
Новый анализатор применяет более агрессивные оптимизации:
- Constant folding (вычисление константных выражений при анализе)
- Predicate pushdown через подзапросы
- Лучшее удаление неиспользуемых столбцов
Breaking changes
Case-sensitive имена функций
Старый анализатор игнорировал регистр имён функций. Новый требует точного соответствия:
-- Старый анализатор: работает
SELECT countdistinct(user_id) FROM events;
SELECT COUNTDISTINCT(user_id) FROM events;
-- Новый анализатор: ошибка
-- Правильно: countDistinct (camelCase)
SELECT countDistinct(user_id) FROM events;
Типичные ошибки миграции:
| Неправильно | Правильно |
|---|---|
| countdistinct | countDistinct |
| grouparray | groupArray |
| arrayuniq | arrayUniq |
| tostartofmonth | toStartOfMonth |
Non-aggregated столбцы в GROUP BY
Старый анализатор мог принять запросы, где столбцы вне GROUP BY не были обёрнуты в агрегатные функции. Новый анализатор строго проверяет это:
-- Старый анализатор: может сработать (результат недетерминирован)
SELECT country, user_id, count()
FROM events
GROUP BY country;
-- Новый анализатор: ошибка
-- user_id не в GROUP BY и не в агрегатной функции
-- Исправление 1: добавить в GROUP BY
SELECT country, user_id, count()
FROM events
GROUP BY country, user_id;
-- Исправление 2: обернуть в агрегатную функцию
SELECT country, any(user_id), count()
FROM events
GROUP BY country;
Квалифицированные ссылки в JOINs
Если столбец с одинаковым именем присутствует в обеих таблицах JOIN, старый анализатор мог угадать нужную таблицу. Новый требует явной квалификации:
-- Старый анализатор: берёт user_id из "нужной" таблицы (иногда ошибаясь)
SELECT user_id, name
FROM events e
JOIN users u ON e.user_id = u.user_id;
-- Новый анализатор: ошибка, user_id неоднозначен
-- Исправление: квалифицировать столбец
SELECT e.user_id, u.name
FROM events e
JOIN users u ON e.user_id = u.user_id;
ALIAS и MATERIALIZED в SELECT *
В старом анализаторе SELECT * не включал столбцы ALIAS и MATERIALIZED. В новом — включает:
CREATE TABLE test (
id UInt32,
name String,
name_upper String ALIAS upper(name),
created_at DateTime DEFAULT now() MATERIALIZED now()
) ENGINE = MergeTree() ORDER BY id;
-- Старый: SELECT * → id, name
-- Новый: SELECT * → id, name, name_upper, created_at
Это может сломать код, который рассчитывает на фиксированное количество столбцов в результате SELECT *.
Ограничения нового анализатора
Не всё переведено на новый анализатор:
| Компонент | Анализатор |
|---|---|
| SELECT, INSERT … SELECT, CREATE TABLE … AS SELECT | Новый (default) |
| Mutations (ALTER TABLE UPDATE/DELETE) | Старый |
| Annoy / usearch index | Удалены в 25.6 — заменены на vector_similarity (HNSW, GA с 25.8) |
| Window Views | Не поддерживается |
Mutations по-прежнему используют старый анализатор. Это означает, что правила из breaking changes (case-sensitive функции, GROUP BY строгость) не применяются к выражениям в ALTER TABLE UPDATE/DELETE.
Путь миграции
1. Тестирование перед обновлением
-- На текущей версии (до 24.3): включить новый анализатор для тестирования
SET enable_analyzer = 1;
-- Выполнить типичные production-запросы
-- Проверить результаты на идентичность
2. Постепенный откат
-- На 24.3+: откатить для конкретной сессии
SET enable_analyzer = 0;
-- Для всего сервера (в config.xml)
-- <profiles>
-- <default>
-- <enable_analyzer>0</enable_analyzer>
-- </default>
-- </profiles>
3. Исправление запросов
Типичный чеклист миграции:
- Проверить регистр имён функций (countdistinct -> countDistinct)
- Убедиться, что все столбцы в SELECT либо в GROUP BY, либо в агрегатной функции
- Квалифицировать неоднозначные столбцы в JOIN (table.column)
- Проверить SELECT * на наличие ALIAS/MATERIALIZED столбцов
Ключевые выводы
- New Analyzer — анализатор запросов по умолчанию с версии 24.3. Управляется настройкой
enable_analyzer. - Улучшения: ранняя валидация, вывод типов, консистентные JOINs, лучшие оптимизации (constant folding, predicate pushdown).
- Breaking changes: case-sensitive функции (countDistinct не countdistinct), строгий GROUP BY, обязательная квалификация столбцов в JOIN, ALIAS/MATERIALIZED в SELECT *.
- Ограничения: mutations по-прежнему используют старый анализатор. Window Views не поддерживаются. Annoy / usearch индексы удалены в 25.6 — мигрировать на
vector_similarity(HNSW, GA с 25.8). - Миграция: тестируйте с
SET enable_analyzer = 1до обновления. Откат:SET enable_analyzer = 0.