Skip to main content
Диагностика медленного запроса начинается с изучения его истории. В этом руководстве показано, как использовать system.query_log для выявления повторяющихся шаблонов медленных запросов, выбора характерного выполнения и анализа потребления ресурсов. Затем с помощью EXPLAIN вы изучите план запроса и сформулируете гипотезу об узком месте, прежде чем изменять запрос или схему.

Перед началом работы

В примерах этого руководства используется таблица nyc_taxi.trips_small_inferred. Чтобы выполнить их в исходном виде, создайте и загрузите таблицу, если ещё не сделали этого:
Размер исходного файла Parquet составляет примерно 5,8 ГБ. Его загрузка может занять несколько минут в зависимости от скорости сети и доступных ресурсов.
Чтобы воспроизвести результаты из журнала запросов, описанные в этом руководстве, после загрузки набора данных выполните все три запроса демонстрационной рабочей нагрузки не менее двух раз. Затем выполните сброс журнала запросов, чтобы завершённые выполнения стали доступны для примеров ниже:
Если вы не можете выполнить SYSTEM FLUSH LOGS, дождитесь автоматической записи журнала запросов, затем повторите первый поиск. При диагностике собственной рабочей нагрузки убедитесь, что system.query_log содержит завершённые выполнения запросов за интересующий вас период времени.

Как это работает

По умолчанию ClickHouse записывает информацию о завершённых запросах в таблицу system.query_log. Каждая запись может содержать длительность запроса, количество прочитанных строк, использование CPU и памяти, а также сведения об активности файлового кэша. Эти показатели помогают выявлять шаблоны медленных запросов и понимать, как они используют ресурсы. Выбрав характерное выполнение, вы можете изучить его план запроса, чтобы определить, на каких этапах запрос может тратить время. В кластере данные журнала запросов хранятся локально на каждом узле. В примерах этого руководства clusterAllReplicas используется для выполнения запроса ко всем репликам, а merge — для включения текущей таблицы system.query_log и всех версионированных таблиц query_log_N, сохранённых после изменений схемы системных таблиц. В каждом примере для журнала запросов предусмотрены вкладки для кластерных и одноузловых развертываний. ClickHouse Cloud предоставляет кластер default, используемый в кластерных примерах. В самоуправляемом развертывании замените default на кластер из system.clusters.
В примерах задаётся skip_unavailable_shards, чтобы временно недоступная реплика не приводила к сбою диагностического запроса. Это особенно полезно при автомасштабировании. Записи с пропущенной реплики не включаются, поэтому результаты могут быть неполными.

Диагностика медленного запроса

Используя завершённые выполнения из журнала запросов, последовательно выполните следующие три шага. Вы выявите повторяющийся шаблон медленного запроса, выберете характерное выполнение и изучите план выполнения запроса.
1

Определите проблемные запросы

Начните с группировки завершённых первичных запросов по normalized_query_hash. Это позволяет отделить регулярно повторяющиеся шаблоны запросов от единичных медленных выполнений. Приведённый ниже запрос сортирует шаблоны по медианной длительности и выводит пример запроса для каждого шаблона:
Используйте executions, чтобы отличить регулярную рабочую нагрузку от единичных запросов. Шаблон с высокой медианной длительностью, частыми выполнениями или высоким потреблением ресурсов — более веский кандидат для анализа, чем один медленный запуск.Для быстрого обзора приведённый ниже запрос выводит самое медленное завершённое выполнение для не более чем пяти различных шаблонов запросов к набору данных NYC Taxi. Из него исключены команды загрузки набора данных и повторные выполнения одного и того же шаблона. На следующем шаге вы сузите историю запросов до выполнений с выбранным выше значением normalized_query_hash.
Поле query_duration_ms содержит длительность запроса в миллисекундах. В приведённых результатах самый долгий запрос выполнялся 2 967 мс.Вы также можете отбирать запросы-кандидаты не по их длительности, а по потреблению ресурсов:
Этот запрос ранжирует последние запросы по использованию памяти и показывает использование CPU. Результаты зависят от рабочей нагрузки и типа развертывания:
2

Выберите типичный запуск запроса

Один медленный запуск может оказаться выбросом из-за разового запроса или временной нагрузки на систему. Прежде чем изучать план запроса, просмотрите несколько завершённых запусков с одинаковым normalized_query_hash: он совпадает у запросов, различающихся только литеральными значениями. Выберите запуск с типичной для этого шаблона длительностью и потреблением ресурсов.Замените значение selected_hash на normalized_query_hash шаблона, который вы хотите исследовать:
  1. Найдите запуски с похожими значениями read_rows и read_bytes.
  2. Сравните query_duration_ms и memory_usage для этих запусков.
  3. Выберите query_id, для которого query_duration_ms ближе всего к медиане.
Результаты из журнала запросов за прошлые периоды могут различаться в зависимости от состояния кэша и нагрузки на систему, поэтому используйте их для выбора запроса для исследования, а не для сравнения результатов оптимизации. Если в журнале запросов недостаточно завершённых запусков, выполните запрос несколько раз в схожих условиях. В следующем руководстве Изоляция узких мест запросов объясняется, как получать контролируемые измерения для сравнения изменений.
Пример результатов журнала запросов показывает, что каждый кандидат прочитал примерно 329,04 млн строк. Для сравнения проверьте количество строк в таблице из примера:
Таблица содержит 329,04 млн строк — примерно столько же указано в read_rows для каждого кандидата. Это говорит о том, что запросы просканировали большую часть или всю таблицу, но не позволяет определить, почему были прочитаны эти строки и оправдан ли такой объём для запроса. Далее изучите план запроса, чтобы понять, как ClickHouse выбрал и обработал данные.
3

Изучите Execution Plan

После выбора характерного запуска используйте EXPLAIN, чтобы посмотреть, как ClickHouse строит план запроса, не выполняя его. В выводе показаны операции, которые ClickHouse предполагает выполнить, и перемещение данных между ними, что помогает лучше интерпретировать показатели из журнала запросов.Подробное описание доступных форматов вывода см. в разделе Понимание выполнения запросов с помощью analyzer. В этом примере EXPLAIN показывает, как ClickHouse планирует читать и фильтровать данные, а также может ли он пропустить часть данных.Вывод представляет собой дерево операций, показывающее, как ClickHouse предполагает читать, фильтровать и обрабатывать данные. Дочерние операции располагаются под родительскими. Начните с наиболее глубокой операции чтения, затем двигайтесь вверх по плану, чтобы увидеть, как ClickHouse преобразует данные в итоговый результат.В этом примере рассмотрите запрос расчёта скорости из результатов журнала запросов:
Вывод содержит следующие операции. Такие сведения, как количество частей и гранул, зависят от способа хранения данных:
Снизу вверх план соотносится с запросом следующим образом:
  1. ReadFromMergeTree считывает данные из nyc_taxi.trips_small_inferred. Отсутствие раздела Indexes в сочетании с read_rows, равным числу строк в таблице, показывает, что ClickHouse читает всю таблицу.
  2. Filter показывает развёрнутое выражение для speed_mph > 30. Для каждой прочитанной строки ClickHouse вычисляет продолжительность поездки и скорость, а затем оставляет только строки со скоростью выше 30 миль в час.
  3. Aggregating вычисляет квантили по отфильтрованным значениям trip_distance.
Этот план позволяет выделить три источника нагрузки для проверки: чтение всех строк, вычисление speed_mph при фильтрации и вычисление квантилей.

Следующие шаги

Далее ознакомьтесь с руководством Выявление узких мест запросов, чтобы узнать, как проверять предполагаемые источники нагрузки в контролируемых условиях. В нём сравниваются запросы всё более простой структуры, чтобы определить, какие операции требуют дальнейшего исследования.
Последнее изменение 28 августа 2026 г.