TGViewer
что-то на инженерном что-то на инженерном @chtotonainzhenernom · 1.17K subscribers
Post #176 1.68K
Ищем проблемный запрос в ClickHouse

Если CPU на пределе, память почти закончилась, а запросы тормозят, то самое время искать виноватого. О том, как это сделать хорошо рассказывает автор статьи на хабре: CPU 80%. Как найти проблемный запрос в ClickHouse? Я оставила важные моменты и дополнила нюансами, которых мне не хватило.

Начинаем с того, что смотрим, что выполняется прямо сейчас:
SELECT
query_id,
user,
elapsed,
formatReadableSize(memory_usage) AS ram,
formatReadableSize(read_bytes) AS read_size,
read_rows,
query
FROM system.processes
ORDER BY elapsed DESC;


system.processes содержит активные запросы, их длительность, память и чтения. Если запрос явно лишний, его можно остановить через:
-- ASYNC (по умолчанию) — команда вернётся сразу, запрос остановится чуть позже
KILL QUERY WHERE query_id = 'xxx' ASYNC;

-- SYNC — ждёт фактической остановки запроса
KILL QUERY WHERE query_id = 'xxx' SYNC;


Но KILL QUERY требует либо права KILL QUERY у пользователя, либо чтобы запрос принадлежал ему самому, иначе получите ошибку.

За анализом завершённых запросов идём в system.query_log. Чтобы получить свежие данные, предварительно можно выполнить:
SYSTEM FLUSH LOGS;


Важно помнить, что query_log локален для каждого узла. На кластере нужно смотреть на каждом узле отдельно или использовать clusterAllReplicas:
SELECT *
FROM clusterAllReplicas('your_cluster', system.query_log)
WHERE event_date >= today()
AND type = 'QueryFinish'
ORDER BY query_duration_ms DESC
LIMIT 20;


Ищем виновников среди пользователей и хостов:
SELECT
user,
client_hostname,
count() AS queries,
round(sum(query_duration_ms) / 1000, 1) AS total_sec,
formatReadableSize(sum(read_bytes)) AS total_read
FROM system.query_log
WHERE event_date >= today()
AND type = 'QueryFinish'
GROUP BY user, client_hostname
ORDER BY total_sec DESC
LIMIT 10;


Когда непонятно, кто именно создает нагрузку, смотрим на user, client_hostname и особенно log_comment. Это очень помогает, если под одной учеткой работает оркестратор или несколько сервисов. Но только в случае, если log_comment уже встроен в ваши сервисные клиенты.

Для поиска конкретно тяжелых запросов сортируем по нужной метрике в зависимости от симптома: query_duration_ms, memory_usage, read_bytes или CPU:
SELECT
query_id,
user,
query_duration_ms / 1000 AS duration_sec,
formatReadableSize(memory_usage) AS ram,
formatReadableSize(read_bytes) AS read_size,
read_rows,
ProfileEvents['OSCPUVirtualTimeMicroseconds'] / 1e6 AS cpu_sec,
query
FROM system.query_log
WHERE event_date >= today()
AND type = 'QueryFinish'
ORDER BY memory_usage DESC -- меняем на нужную метрику
LIMIT 20;


При этом стоит знать про значения поля type, это поможет при отладке не только медленных, но и падающих запросов:
⭐️QueryStart -> Запрос начался
⭐️QueryFinish -> Успешно завершился
⭐️ExceptionBeforeStart -> Ошибка до старта
⭐️ExceptionWhileProcessing -> Ошибка в процессе

Для поиска падающих запросов:
WHERE type IN ('ExceptionBeforeStart', 'ExceptionWhileProcessing')


Для профилактики появления проблемных запросов полезно использовать:
EXPLAIN indexes = 1
SELECT ... -- подозрительный запрос


Он показывает, насколько запрос реально использует ключ сортировки и сколько гранул будет прочитано. Если читается почти вся таблица, проблема, скорее всего, в фильтре или в структуре хранения. Если нужно понять pipeline выполнения целиком:
EXPLAIN PIPELINE
SELECT ...;


Еще один уровень защиты - это пользовательские ограничения на уровне профиля или отдельного пользователя. Они не дают одному запросу положить весь кластер:
max_execution_time = 60          -- максимум 60 секунд на запрос
max_memory_usage = 10000000000 -- максимум ~10 GB RAM на запрос
max_rows_to_read = 1000000000 -- максимум 1 млрд строк

В большинстве случаев этого уже хватает, чтобы за минуты найти тяжелый запрос и понять, что именно чинить.
  • ❤ 26
  • 👍 10
  • 🔥 3
More from @chtotonainzhenernom
  1. Sep 21, 20265 октября начнется 19-й поток программы Data Engineer от Newprolab Программа для junior- и…
  2. Aug 1, 2026На днях стала свидетелем неприятной ситуации. Началось все с того, что я провела K. мок-со…
  3. Jun 13, 2026StarRocks DB В предыдущем посте я упомянула, что сейчас активно занимаюсь задачами миграци…
  4. May 23, 2026Сто лет ничего не писала, потому что было очень много настоящей инженерной работы. Моя ком…
  5. Mar 31, 2026Хочу поделиться классной штукой - симулятором карьерного пути дата инженера от Джо Рейса,…
  6. Feb 25, 2026Разбираемся с unionByName() в Spark Представьте, что у вас есть два датафрейма из разных и…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →