Learning Platform
Глоссарий Troubleshooting
Урок 07.07 · 20 мин
Средний
New Analyzerenable_analyzerQuery OptimizationBreaking ChangesMigrationGROUP BYType Inference

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;

Типичные ошибки миграции:

НеправильноПравильно
countdistinctcountDistinct
grouparraygroupArray
arrayuniqarrayUniq
tostartofmonthtoStartOfMonth

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. Исправление запросов

Типичный чеклист миграции:

  1. Проверить регистр имён функций (countdistinct -> countDistinct)
  2. Убедиться, что все столбцы в SELECT либо в GROUP BY, либо в агрегатной функции
  3. Квалифицировать неоднозначные столбцы в JOIN (table.column)
  4. Проверить SELECT * на наличие ALIAS/MATERIALIZED столбцов

Ключевые выводы

  1. New Analyzer — анализатор запросов по умолчанию с версии 24.3. Управляется настройкой enable_analyzer.
  2. Улучшения: ранняя валидация, вывод типов, консистентные JOINs, лучшие оптимизации (constant folding, predicate pushdown).
  3. Breaking changes: case-sensitive функции (countDistinct не countdistinct), строгий GROUP BY, обязательная квалификация столбцов в JOIN, ALIAS/MATERIALIZED в SELECT *.
  4. Ограничения: mutations по-прежнему используют старый анализатор. Window Views не поддерживаются. Annoy / usearch индексы удалены в 25.6 — мигрировать на vector_similarity (HNSW, GA с 25.8).
  5. Миграция: тестируйте с SET enable_analyzer = 1 до обновления. Откат: SET enable_analyzer = 0.
PostgreSQL: pipeline запроса — parser, rewriter, planner, executor Spark SQL: Analysis — resolved logical plan и catalog lookup

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 4. После обновления ClickHouse до 24.3 запрос SELECT countdistinct(user_id) FROM events перестал работать. Что изменилось?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 8