ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

MySQL slow query log и digest-анализ: находим и чиним медленные запросы

Пошагово включаем MySQL slow query log без лишней нагрузки: пороги, формат, ротация. Затем делаем digest-анализ через pt-query-digest и сверяем картину с performance_schema, чтобы быстро выбрать, что оптимизировать первым.
MySQL slow query log и digest-анализ: находим и чиним медленные запросы

Медленные запросы в MySQL редко «живут» по одному: чаще это несколько типовых паттернов (одинаковая форма запроса с разными параметрами), которые постепенно разгоняют нагрузку на CPU/IO и увеличивают время ответа. Правильный подход — не вылавливать единичные запросы вручную, а включить slow query log, собрать статистику за репрезентативное окно и сделать digest-анализ: сгруппировать похожие запросы, чтобы понять, что оптимизировать в первую очередь.

В этой инструкции разберём два практичных источника правды:

  • MySQL slow query log — фиксирует «медленные» запросы по порогу и дополнительные события (например, неиспользование индексов).

  • performance_schema — даёт агрегированную статистику внутри сервера, помогает проверять гипотезы и смотреть разрезы по событиям/стейтментам.

А для приоритезации будем использовать pt-query-digest (Percona Toolkit) — он превращает «сырые» записи slow log в понятный рейтинг по суммарному времени, количеству, перцентилям и «эффективности» чтения строк.

Когда slow query log действительно полезен (и когда нет)

Slow log хорошо работает, когда нужно быстро увидеть реальных «виновников» задержек и оценить их вклад в общее время выполнения запросов.

  • Нужно найти запросы, которые чаще всего создают задержки, и понять их долю в суммарном времени.

  • Есть подозрение на регресс после релиза: «раньше было быстрее».

  • Нужно оценить эффект индекса/переписывания: сравнение «до/после» на одинаковом окне.

Но бывают ситуации, где slow log даст неполную картину:

  • Запросы быстрые, но их слишком много (QPS высокий, latency низкая): упереться можно в конкуренцию, сеть, пул соединений, fsync, буфер-пул, фоновые задачи.

  • Проблема не в SQL, а в инфраструктуре: IOPS просел, место заканчивается, начался своп, throttling, выросли сетевые задержки.

Практика: начинайте со slow log, потому что он быстро даёт «ТОП-10 виновников». Затем подтверждайте выводы через performance_schema и план выполнения (EXPLAIN/EXPLAIN ANALYZE), чтобы не лечить симптомы.

Включаем MySQL slow query log безопасно

Само включение slow log обычно не «ломает» прод, но важно выбрать порог, формат и продумать ротацию, иначе вы быстро упрётесь в размер файла и лишний IO.

Проверяем текущие значения

mysql -e "SHOW VARIABLES LIKE 'slow_query_log%';"
mysql -e "SHOW VARIABLES LIKE 'long_query_time';"
mysql -e "SHOW VARIABLES LIKE 'log_output';"

Ключевые переменные:

  • slow_query_log — включён ли сбор.

  • slow_query_log_file — путь к файлу.

  • long_query_time — порог «медленности» в секундах (дробные значения допустимы).

  • log_output — куда писать (FILE, TABLE). Для продакшна чаще всего разумнее FILE.

Включаем на лету (временная настройка)

Если нужно быстро собрать диагностику на 15–60 минут, включайте динамически:

mysql -e "SET GLOBAL log_output = 'FILE';"
mysql -e "SET GLOBAL slow_query_log = 'ON';"
mysql -e "SET GLOBAL long_query_time = 0.2;"

0.2 секунды — пример. Для нагруженных систем часто начинают с 0.51, чтобы не утонуть в объёме. Для «ловли» коротких подвисаний можно временно опускать до 0.050.1, но обязательно контролировать размер файла.

Фиксируем в конфиге (постоянно)

Для постоянного сбора задайте параметры в конфиге MySQL (расположение зависит от дистрибутива):

[mysqld]
slow_query_log=ON
slow_query_log_file=/var/log/mysql/mysql-slow.log
long_query_time=0.2
log_output=FILE

Если меняли только динамические параметры — перезапуск не обязателен. Но путь к файлу, права на каталог и SELinux/AppArmor (если применимо) должны быть корректными, иначе лог просто не начнёт писаться.

Что делать с log_queries_not_using_indexes

Параметр log_queries_not_using_indexes кажется «волшебной кнопкой», но часто превращается в шум: маленькие таблицы и справочники могут читаться полным сканом вполне нормально, а оптимизатор иногда осознанно выбирает non-index plan.

Рекомендация: включайте опцию только на короткое окно и лучше вместе с более высоким порогом long_query_time.

mysql -e "SET GLOBAL log_queries_not_using_indexes = 'ON';"
mysql -e "SET GLOBAL long_query_time = 0.5;"

Фрагмент конфигурации MySQL с настройками slow query log

Ротация slow log без боли

Главная операционная проблема slow log — размер и сопровождение. Если файл растёт без контроля, вы упрётесь в занятый диск или получите неудобный анализ из-за десятков гигабайт.

Базовый принцип: ротация должна сопровождаться переподключением MySQL к файлу логов через FLUSH SLOW LOGS. Если просто переименовать файл, mysqld может продолжить писать в старый файловый дескриптор.

Минимальный ручной сценарий

mv /var/log/mysql/mysql-slow.log /var/log/mysql/mysql-slow.log.1
mysql -e "FLUSH SLOW LOGS;"
gzip -f /var/log/mysql/mysql-slow.log.1

В продакшне лучше использовать системную ротацию, но логика остаётся той же: после rotate выполняйте FLUSH SLOW LOGS.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Digest-анализ: зачем он нужен и как его читать

Сырые записи slow log неудобны: там много повторов одного и того же запроса с разными значениями. Digest — это нормализованная форма SQL, где константы заменяются плейсхолдерами. Например, два запроса:

  • SELECT * FROM orders WHERE id = 123

  • SELECT * FROM orders WHERE id = 456

В digest-логике это один шаблон, который оптимизируется один раз (индекс, переписывание запроса, изменение схемы).

Устанавливаем pt-query-digest

На Debian/Ubuntu Percona Toolkit часто доступен из стандартных репозиториев дистрибутива или из репозиториев вендора (названия и доступность пакета зависят от ОС и версии).

apt-get update
apt-get install -y percona-toolkit

На RHEL-подобных системах:

yum install -y percona-toolkit

Если пакет недоступен, ставьте именно пакетным способом под вашу ОС (так проще обновлять и откатывать), а не копируйте скрипты вручную на прод.

Строим отчёт по slow log

Самый частый сценарий — получить общий отчёт за период:

pt-query-digest /var/log/mysql/mysql-slow.log > /root/slow-report.txt

В отчёте удобно смотреть на несколько метрик одновременно:

  • Total — суммарное время, которое «съел» шаблон запроса (часто важнее максимальной задержки).

  • Count — частота. Частые «слегка медленные» запросы иногда вреднее редких «очень медленных».

  • 95% / stddev — хвосты распределения и разброс. Большой 95-й перцентиль обычно означает пики и нестабильность.

  • Rows examine / Rows sent — грубый индикатор неэффективности (много читаем, мало отдаём).

Ограничиваем окно по времени

Если лог большой, анализируйте конкретный инцидентный период:

pt-query-digest --since '2025-12-25 10:00:00' --until '2025-12-25 11:00:00' /var/log/mysql/mysql-slow.log > /root/slow-incident.txt

Как перейти от digest к конкретному SQL

  1. Берите самый дорогой digest по Total time или по комбинации time+count.

  2. Ищите в коде приложения соответствующий запрос по форме (обычно он узнаваем).

  3. Воспроизводите на стенде и смотрите EXPLAIN/EXPLAIN ANALYZE (зависит от версии MySQL).

  4. Вносите одно изменение за раз (индекс или переписывание), затем повторяйте сбор и сравнивайте «до/после».

Performance Schema: когда slow log недостаточно

performance_schema — встроенный инструмент MySQL для сбора статистики по событиям (ожидания, стадии, SQL statements). В отличие от slow log, он показывает агрегированную картину даже по быстрым запросам и помогает понять «среднюю температуру» нагрузки.

Проверяем, включен ли performance_schema

mysql -e "SHOW VARIABLES LIKE 'performance_schema';"

Если выключен, включение обычно требует изменения конфигурации и перезапуска:

[mysqld]
performance_schema=ON

Дальше проверьте, что у вас включены нужные инструменты и потребители. Включать «всё подряд» не всегда разумно: это может дать лишние накладные расходы и объём данных.

Быстрый рейтинг запросов по суммарному времени

В MySQL 8 удобно начать с таблиц сводной статистики по statements. Пример запроса (названия колонок могут отличаться между версиями):

mysql -e "SELECT DIGEST_TEXT, COUNT_STAR, SUM_TIMER_WAIT, AVG_TIMER_WAIT FROM performance_schema.events_statements_summary_by_digest ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;"

Это digest на стороне MySQL: нормализованный текст, количество выполнений, суммарное и среднее время. Плюс — не нужен файл логов. Минус — нужно контролировать окно наблюдения и понимать, когда статистика сбрасывалась.

Сбрасываем статистику перед замером

Чтобы корректно сравнить «до/после» оптимизации, удобно сбрасывать summary-таблицы на тестовом окне (и осознавать последствия для наблюдаемости):

mysql -e "TRUNCATE TABLE performance_schema.events_statements_summary_by_digest;"

Если вы строите отказоустойчивую схему (репликация, переключения, раздельные роли), заранее продумайте, где именно включать диагностику и как собирать логи с нужного узла. По теме переключений может пригодиться материал про failover на GTID и semi-sync в MySQL.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Типовой рабочий процесс: от инцидента к фиксу

  1. Определите окно проблемы: когда начались задержки, как долго длились, были ли релизы/миграции.

  2. Включите slow log на время окна (или анализируйте уже собранный), выставьте long_query_time так, чтобы получить управляемый объём.

  3. Соберите digest-отчёт через pt-query-digest и выберите 3–5 лидеров по суммарному времени.

  4. Подтвердите через performance_schema, что этот digest действительно доминирует (особенно если slow log включали кратко).

  5. Сделайте EXPLAIN на типичных параметрах, проверьте индексы, селективность и сортировки.

  6. Внесите одно изменение за раз и повторите замер «до/после» на сопоставимом окне.

Отчёт pt-query-digest в терминале с рейтингом запросов по суммарному времени

На что смотреть в самом slow log

Даже если вы работаете через digest, полезно понимать базовые поля записи, чтобы не пропустить важные симптомы:

  • Query_time — время выполнения.

  • Lock_time — время ожидания блокировок. Если оно большое, причина может быть в конкуренции транзакций, а не в индексе.

  • Rows_examined — сколько строк просмотрели.

  • Rows_sent — сколько строк отдали.

Если Lock_time заметно растёт, не спешите добавлять индексы: сначала проверьте длительные транзакции, шаблоны обновлений и конкурирующие запросы. Это часто даёт больший эффект, чем «индекс на всякий случай».

Частые ошибки при включении и анализе

Слишком низкий порог long_query_time навсегда

Порог 0.01 секунды на постоянной основе почти гарантированно создаст огромный лог и дополнительную нагрузку на IO. Делайте так только на короткий период и под контроль диска.

Анализ по «самому медленному запросу», а не по суммарному времени

Один запрос на 20 секунд раз в сутки может быть неприятным, но тысяча запросов по 200 мс каждую минуту убьёт latency намного сильнее. В отчётах всегда оценивайте общий вклад (Total time).

Смешивание разных нагрузочных периодов

Если прогнать digest по логам за неделю, в топ может попасть ночная пакетная задача, а ваша дневная проблема будет спрятана ниже. Отделяйте окна: рабочие часы, ночные джобы, периоды релизов.

Оптимизация без понимания данных

Индекс «по колонке» часто не решает проблему, если условие не селективно или если запрос упирается в сортировку/группировку по другому полю. Всегда смотрите план выполнения и оценку кардинальности.

Мини-чеклист: что подготовить заранее

  • Выделенный каталог под логи MySQL с понятными правами и мониторингом места.

  • Ротация slow log и проверка, что FLUSH SLOW LOGS вызывается после ротации.

  • pt-query-digest на сервере или на отдельной админ-машине для анализа.

  • performance_schema включён (если возможно) и вы знаете, как быстро снять топ по digest.

Итог

MySQL slow query log — быстрый способ получить список реальных проблемных запросов на продакшне. pt-query-digest превращает «шумный» лог в понятный digest-рейтинг и помогает выбрать, что чинить первым. А performance_schema дополняет картину: показывает агрегаты на стороне сервера и помогает отличить «медленные запросы» от «ожиданий и конкуренции».

Если выстроить простой процесс «включили лог → сделали digest → подтвердили через performance_schema → починили → сравнили до/после», оптимизация MySQL превращается в повторяемую операционную процедуру, а не в гадание.

На системах, где важна восстановимость и расследование инцидентов, полезно заранее продумать стратегию бэкапов и точку восстановления. По теме может пригодиться заметка про PITR в MySQL/MariaDB через binlog и GTID.

Если вы выбираете площадку под MySQL, обращайте внимание на предсказуемый диск и возможность быстро включать диагностику без сюрпризов по ресурсам — на VDS это обычно проще контролировать, чем в сильно ограниченных окружениях.

Поделиться статьей

Вам будет интересно

Fail2ban 2025: защита от SSH brute force и nginx basic auth, настройка bantime/ignoreip и отладка OpenAI Статья написана AI (GPT 5)

Fail2ban 2025: защита от SSH brute force и nginx basic auth, настройка bantime/ignoreip и отладка

Fail2ban в 2025 всё так же спасает от перебора паролей: читает логи, находит ошибки входа и банит IP через фаервол. В статье — нас ...
2FA для SSH и sudo на Linux: TOTP через pam_google_authenticator без лишней боли OpenAI Статья написана AI (GPT 5)

2FA для SSH и sudo на Linux: TOTP через pam_google_authenticator без лишней боли

Практический гайд по внедрению TOTP-2FA в Linux через pam_google_authenticator: установка, создание секрета, настройка PAM и OpenS ...
SLO-мониторинг с node_exporter и blackbox_exporter: latency, доступность и error budget OpenAI Статья написана AI (GPT 5)

SLO-мониторинг с node_exporter и blackbox_exporter: latency, доступность и error budget

Пошагово собираем SLO-мониторинг на Prometheus: node_exporter для диагностики хоста и blackbox_exporter для внешних проверок. Счит ...