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

Давайте рассмотрим каждую сущность в действии во время выполнения запроса. Мы будем использовать несколько запросов и затем анализировать их с помощью оператора EXPLAIN
.
Парсер
Цель парсера — преобразовать текст запроса в AST (дерево абстрактного синтаксиса). Этот этап можно визуализировать с помощью EXPLAIN AST
:
Вывод представляет собой дерево абстрактного синтаксиса, которое можно визуализировать следующим образом:

Каждый узел имеет соответствующих дочерних узлов, и общее дерево представляет собой общую структуру вашего запроса. Это логическая структура, помогающая в обработке запроса. С точки зрения конечного пользователя (если не интересует выполнение запроса), она не слишком полезна; этот инструмент в основном используется разработчиками.
Анализатор
На данный момент у ClickHouse есть две архитектуры для Анализатора. Вы можете использовать старую архитектуру, установив: enable_analyzer=0
. Новая архитектура включена по умолчанию. Мы здесь опишем только новую архитектуру, поскольку старая будет устаревать, как только новый анализатор станет общедоступным.
Новая архитектура должна предоставить нам лучшую основу для улучшения производительности ClickHouse. Однако, так как она является основным компонентом этапов обработки запроса, она может также оказать негативное влияние на некоторые запросы, и уже есть известные несовместимости. Вы можете вернуться к старому анализатору, изменив настройку enable_analyzer
на уровне запроса или пользователя.
Анализатор — это важный этап выполнения запроса. Он принимает AST и преобразует его в дерево запроса. Основное преимущество дерева запроса перед AST заключается в том, что многие компоненты будут разрешены, например, хранилище. Мы также знаем, из какой таблицы читать, псевдонимы также разрешены, и дерево знает о различных используемых типах данных. Со всеми этими преимуществами анализатор способен применять оптимизации. Оптимизации работают через «проходы». Каждый проход ищет разные оптимизации. Вы можете увидеть все проходы здесь, давайте увидим это на практике с нашим предыдущим запросом:
Между двумя выполнениями вы можете увидеть разрешение псевдонимов и проекций.
Планировщик
Планировщик берет дерево запроса и строит план запроса из него. Дерево запроса говорит нам, что мы хотим сделать с конкретным запросом, а план запроса говорит нам, как мы будем это делать. Дополнительные оптимизации будут выполняться в рамках плана запроса. Вы можете использовать EXPLAIN PLAN
или EXPLAIN
, чтобы увидеть план запроса (EXPLAIN
выполнит EXPLAIN PLAN
).
Хотя это дает нам некоторую информацию, мы можем получить больше. Например, возможно, мы хотим знать имя колонки, на которой нам нужны проекции. Вы можете добавить заголовок к запросу:
Теперь вы знаете имена колонок, которые необходимо создать для последней проекции (minimum_date
, maximum_date
и percentage
), но вы также можете захотеть видеть все действия, которые необходимо выполнить. Вы можете сделать это, установив actions=1
.
Теперь вы видите все входные данные, функции, псевдонимы и типы данных, которые используются. Вы также можете увидеть некоторые оптимизации, которые планировщик собирается применить здесь.
Конвейер Запросов
Конвейер запросов генерируется из плана запроса. Конвейер запросов очень похож на план запроса, с тем отличием, что это не дерево, а граф. Он подчеркивает, как ClickHouse будет выполнять запрос и какие ресурсы будут использоваться. Анализ конвейера запросов очень полезен для определения узкого места в терминах входных/выходных данных. Давайте рассмотрим наш предыдущий запрос и посмотрим на выполнение конвейера запросов:
Внутри круглых скобок находится шаг плана запроса, а рядом с ним — процессор. Это отличная информация, но поскольку это граф, было бы неплохо визуализировать его как таковой. У нас есть настройка graph
, которую мы можем установить на 1 и указать формат вывода как TSV:
Затем вы можете скопировать этот вывод и вставить его сюда, и это сгенерирует следующий график:

Белый прямоугольник соответствует узлу конвейера, серый прямоугольник соответствует шагам плана запроса, а x
, за которым следует число, соответствует количеству входных/выходных данных, которые используются. Если вы не хотите видеть их в компактной форме, вы всегда можете добавить compact=0
:

Почему ClickHouse не считывает таблицу с использованием нескольких потоков? Давайте попробуем добавить больше данных в нашу таблицу:
Теперь давайте снова запустим наш запрос EXPLAIN
:

Таким образом, исполнение решило не параллелить операции, потому что объем данных был недостаточно высоким. После добавления большего числа строк, исполнитель решил использовать несколько потоков, как показано на графе.
Исполнитель
Наконец, последний шаг выполнения запроса выполняется исполнителем. Он берет конвейер запроса и выполняет его. Существуют различные типы исполнителей, в зависимости от того, выполняете ли вы SELECT
, INSERT
или INSERT SELECT
.