Что такое Slow Query Log
Slow Query Log фиксирует SQL-запросы, которые выполняются дольше заданного времени. Это главный инструмент диагностики производительности базы данных: он показывает, какие запросы нагружают сервер, и помогает найти запросы, которым нужны индексы.
Включение через my.cnf
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
min_examined_row_limit = 100# Применить без перезапуска (MySQL 5.1+)
mysql -u root -p -e "
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
SET GLOBAL long_query_time = 1;
SET GLOBAL log_queries_not_using_indexes = 1;"Параметры Slow Query Log
| Параметр | Значение | Описание |
|---|---|---|
long_query_time | 1–2 сек | Запросы длиннее этого времени логируются |
log_queries_not_using_indexes | ON | Логировать запросы без индексов |
min_examined_row_limit | 100 | Минимум просмотренных строк для логирования |
Анализ через mysqldumpslow
# Топ 10 самых медленных запросов
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
# Топ 10 по количеству выполнений
mysqldumpslow -s c -t 10 /var/log/mysql/slow.log
# С сортировкой по avg time
mysqldumpslow -s at -t 10 /var/log/mysql/slow.logАнализ через pt-query-digest (рекомендуется)
# Установка Percona Toolkit
sudo apt install percona-toolkit
# Анализ slow log
pt-query-digest /var/log/mysql/slow.log
# Топ запросы за последние 24 часа
pt-query-digest --since=24h /var/log/mysql/slow.log
# Вывести в файл
pt-query-digest /var/log/mysql/slow.log > /tmp/slow_report.txtИспользование EXPLAIN для оптимизации
-- Анализ конкретного запроса
EXPLAIN SELECT * FROM orders WHERE status = 'pending' AND created_at > '2024-01-01';
-- Подробный анализ (MySQL 5.6+)
EXPLAIN FORMAT=JSON SELECT ...;
-- Выполнить и показать реальный план
EXPLAIN ANALYZE SELECT ...;type (должно быть ref/eq_ref/const, не ALL), rows (меньше = лучше) и Extra (Using filesort, Using temporary — плохие признаки).Разбор типичных строк из slow.log
Сама по себе запись в логе не говорит, где проблема — нужно смотреть на конкретные поля.
# Time: 2026-09-30T10:15:32.123456Z
# User@Host: app_user[app_user] @ localhost []
# Query_time: 4.812345 Lock_time: 0.000112 Rows_sent: 1 Rows_examined: 842103
SELECT * FROM orders WHERE customer_email = 'user@example.com';Query_time — сколько запрос выполнялся целиком. Lock_time — сколько из этого времени ушло на ожидание блокировки; если оно велико относительно Query_time, дело не в отсутствии индекса, а в конкуренции за строку или таблицу. Rows_examined много больше Rows_sent (842103 против 1) — классический признак отсутствующего индекса: MySQL прочитал почти всю таблицу, чтобы найти одну строку.
Ошибка Lock wait timeout exceeded в контексте slow log
Если в slow.log регулярно попадаются запросы с большим Lock_time, а в логе ошибок приложения встречается Lock wait timeout exceeded; try restarting transaction — это одна и та же проблема: долгая транзакция удерживает блокировку строки, и другие запросы простаивают в очереди сверх innodb_lock_wait_timeout (по умолчанию 50 секунд). Slow log в этом случае покажет не только виновника (тот, что удерживает блокировку), но и жертв — короткие по логике, но долгие по факту запросы.
Когда slow log не поможет
Slow log логирует только уже завершённые запросы — если сервер завис из-за запроса, который выполняется часами и ещё не закончился, в логе его не будет, пока он не завершится или не оборвётся по таймауту. Для таких случаев нужен SHOW PROCESSLIST в реальном времени, а не анализ лога постфактум. Также slow log не покажет причину нагрузки от большого количества быстрых запросов (по 5 мс каждый, но 50 000 в секунду) — здесь нужен профилировщик уровня приложения или SHOW STATUS LIKE 'Questions' для оценки общего QPS. Дополнительно стоит смотреть на SHOW STATUS LIKE 'Slow_queries' в динамике — резкий рост счётчика за короткий период точнее укажет на момент деградации, чем разовый просмотр файла лога.
Ротация и вес slow log на диске
| Настройка | Значение | Зачем |
|---|---|---|
long_query_time = 0.5 | для отладки | Ловит больше запросов, но лог растёт быстрее — включайте временно |
| logrotate для slow.log | ежедневно, хранить 7 копий | Не даёт логу занять весь диск на нагруженном сервере |
log_slow_admin_statements | OFF по умолчанию | Включайте, только если подозреваете медленные ALTER/OPTIMIZE |
log_throttle_queries_not_using_indexes | 60 | Не более 60 записей в минуту для запросов без индекса — иначе лог зальёт диск при массовом Full Scan |
Настройка общих параметров, влияющих на диск и память сервера, разобрана в статье про оптимизацию my.cnf, а типовые проблемы отсутствующих индексов — в статье про индексы MySQL.