Skip to main content
ClickHouse обрабатывает запросы чрезвычайно быстро, но выполнение запроса — не такой уж простой процесс. Давайте попробуем понять, как выполняется запрос SELECT. Для наглядности добавим в таблицу ClickHouse немного данных:
Теперь, когда в ClickHouse есть данные, можно выполнить несколько запросов и понять, как они исполняются. Выполнение запроса разбивается на множество этапов. Каждый этап выполнения запроса можно проанализировать и диагностировать с помощью соответствующего запроса EXPLAIN. Эти этапы показаны на схеме ниже: Давайте посмотрим, как каждый компонент работает в процессе выполнения запроса. Мы возьмем несколько запросов, а затем разберем их с помощью оператора EXPLAIN.

Парсер

Задача парсера — преобразовать текст запроса в AST (абстрактное синтаксическое дерево). Этот шаг можно наглядно представить с помощью EXPLAIN AST:
Результатом является абстрактное синтаксическое дерево, которое можно визуализировать, как показано ниже: У каждого узла есть соответствующие дочерние элементы, а всё дерево в целом отражает общую структуру вашего запроса. Это логическая структура, помогающая обрабатывать запрос. С точки зрения конечного пользователя (если только его не интересует выполнение запроса) она не слишком полезна; этот инструмент в основном используется разработчиками.

Анализатор

В настоящее время в ClickHouse есть две архитектуры анализатора. Чтобы использовать старую архитектуру, задайте: enable_analyzer=0. Текущая архитектура включена по умолчанию, начиная с ClickHouse 24.3. Здесь мы будем описывать только текущую архитектуру, поскольку старая объявлена устаревшей и сохраняется только для обратной совместимости.
Текущая архитектура должна обеспечить более качественную основу для повышения производительности ClickHouse. Однако, поскольку это фундаментальный компонент процесса обработки запросов, она также может негативно повлиять на некоторые запросы, и у нее есть известные несовместимости. Вы можете вернуться к старой архитектуре, изменив настройку enable_analyzer на уровне запроса или пользователя.
Анализатор — важный этап выполнения запроса. Он принимает AST и преобразует его в дерево запроса. Основное преимущество дерева запроса перед AST в том, что многие компоненты в нем уже будут разрешены, например хранилище. Мы также уже знаем, из какой таблицы читать, разрешены псевдонимы, а дереву известны различные используемые типы данных. Благодаря этому анализатор может применять оптимизации. Эти оптимизации реализованы в виде “проходов”. Каждый проход ищет свои варианты оптимизации. Вы можете увидеть все проходы здесь, а теперь давайте посмотрим, как это работает на практике, на нашем предыдущем запросе:
Между этими двумя выполнениями видно, как разрешаются псевдонимы и проекции.

Планировщик

Планировщик берет дерево запроса и на его основе строит план запроса. Дерево запроса показывает, что именно мы хотим сделать с конкретным запросом, а план запроса — как мы будем это делать. В рамках плана запроса также выполняются дополнительные оптимизации. Чтобы посмотреть план запроса, можно использовать EXPLAIN PLAN или EXPLAIN (EXPLAIN выполнит EXPLAIN PLAN).
Хотя это и дает нам некоторую информацию, можно узнать и больше. Например, нам может понадобиться узнать имя столбца, для которого нужны проекции. Вы можете добавить заголовок в запрос:
Итак, теперь вы знаете имена столбцов, которые нужно создать для последней Projection (minimum_date, maximum_date и percentage), но вам также может понадобиться более подробная информация обо всех действиях, которые необходимо выполнить. Для этого задайте actions=1.
Теперь вы можете видеть все используемые входные данные, функции, псевдонимы и типы данных. С некоторыми оптимизациями, которые планировщик будет применять, можно ознакомиться здесь.

Конвейер запроса

Конвейер запроса формируется на основе плана запроса. Он очень похож на план запроса, однако, в отличие от него, представляет собой не дерево, а граф. Конвейер наглядно показывает, как ClickHouse будет выполнять запрос и какие ресурсы при этом задействует. Анализ конвейера запроса особенно полезен для выявления узких мест с точки зрения операций ввода/вывода. Рассмотрим предыдущий запрос и изучим выполнение его конвейера:
В скобках указан шаг плана запроса, а рядом с ним — процессор. Это весьма полезная информация, однако, поскольку перед нами граф, было бы удобно визуализировать его соответствующим образом. Для этого существует настройка graph, которой можно присвоить значение 1, указав формат вывода TSV:
Затем скопируйте этот вывод и вставьте его сюда — будет сгенерирован следующий граф: Белый прямоугольник соответствует узлу конвейера, серый прямоугольник — шагам плана запроса, а символ x, за которым следует число, обозначает количество используемых входов/выходов. Если вы не хотите видеть их в компактном виде, всегда можно добавить compact=0:
Почему ClickHouse не читает данные из таблицы в несколько потоков? Попробуем добавить в таблицу больше данных:
Теперь давайте снова выполним наш запрос EXPLAIN:
Итак, исполнитель решил не выполнять операции параллельно, потому что объём данных был недостаточно большим. После добавления большего количества строк исполнитель решил использовать несколько потоков, как показано на графе.

Исполнитель

Наконец, завершающий этап выполнения запроса осуществляется исполнителем. Он берёт конвейер выполнения запроса и запускает его. Существуют разные типы исполнителей — в зависимости от того, выполняете ли вы SELECT, INSERT или INSERT SELECT.
Последнее изменение 23 июля 2026 г.