Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як знайти повільні запити в MySQL за допомогою slow query log?

Журнал повільних запитів записує запити, що виконувалися довше заданого порогу. Це найпростіший спосіб дізнатися, що саме гальмує базу на продакшені.

Увімкнення без перезапуску:

SET PERSIST slow_query_log = ON;
SET PERSIST long_query_time = 1;      -- секунди, можна дробові: 0.5
SET PERSIST slow_query_log_file = '/var/log/mysql/slow.log';

За замовчуванням long_query_time - 10 секунд, а для вебзастосунку повільним є вже запит на 200-500 мс.

Додаткові налаштування:

  • log_queries_not_using_indexes = ON - записувати й запити без індексів, навіть швидкі. Корисно на розробці; на продакшені шумно (обмежує log_throttle_queries_not_using_indexes);
  • min_examined_row_limit - не писати запити, що прочитали менше N рядків;
  • log_slow_admin_statements - включити ALTER TABLE, OPTIMIZE TABLE тощо;
  • log_output = 'TABLE' - писати в таблицю mysql.slow_log замість файлу (зручно для керованих хмарних баз).

Що є в записі:

# Query_time: 2.415  Lock_time: 0.000  Rows_sent: 20  Rows_examined: 1850234
SELECT * FROM orders WHERE status = 'paid' ORDER BY created_at DESC LIMIT 20;

Співвідношення Rows_examined до Rows_sent - головна підказка: прочитано майже два мільйони рядків, щоб повернути 20. Тут явно бракує індексу.

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

mysqldumpslow -s t -t 10 /var/log/mysql/slow.log   # топ-10 за сумарним часом
pt-query-digest /var/log/mysql/slow.log            # детальніший звіт (Percona Toolkit)

Часто винуватцем виявляється не найповільніший запит, а запит на 50 мс, що виконується 100 000 разів на годину.

Альтернатива без журналу - Performance Schema вже збирає статистику за нормалізованими запитами:

SELECT query, exec_count, total_latency, rows_examined_avg
FROM sys.statement_analysis
ORDER BY total_latency DESC LIMIT 10;

У Laravel допоміжно: DB::whenQueryingForLongerThan() для сповіщень про сумарний час запитів у межах запиту, Telescope чи Pulse (картка повільних запитів) на рівні застосунку. Але журнал MySQL бачить і запити від черг, крон-задач і сторонніх клієнтів.

Докладніше в документації: Журнал повільних запитів

1

Схожі питання