Що таке 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.