Анализ медленных запросов в MySQL

Иногда нам нужно, определить почему SQL обрабатывается медленно. Конечно, это может зависеть от конфигурации, от железа, от неправильной схемы и от неправильного SQL запроса. Один из инструментов определения это лог медленных запросов.

Чтобы включить лог медленных запросов, нужно открыть конфигурационный файл MySQL (путь может отличаться):

sudo gedit /etc/mysql/my.cnf

и изменить настройки:

log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 1

log_slow_queries - указывает путь к файлу настроек long_query_time - указывает минимальное время выполнения запроса, после которого он считается медленным в секундах,

После этого необходимо перезапустить MySQL:

/etc/init.d/mysql restart

После этого в файл /var/log/mysql/mysql-slow.log будут попадать медленные запросы которые больше заданого времени в конфиге

mysqldumpslow

Для обработки и анализа лога медленных запросов предназначена консольная команда mysqldumpslow с таким синтаксисом: mysqldumpslow [options] [log_file ...].

mysqldumpslow группирует похожие запросы, заменяя числа и строки в запросах на N и 'S'. Наиболее полезные опции это:

  • -s sort_type — тип сортировки запроса, обычно используются типы:
    • t — по времени запроса,
    • at — по среднему времени запроса,
    • c — по количеству запросов;
  • -t N — показывает только N запросов при выводе;
  • -g pattern — фильтрует запросы по шаблону pattern (в стиле команды grep).

По умолчанию используется сортировка по среднему времени запроса -s at.

Пример, чтобы получить 10 самых частых медленных запросов в файл top10-by-count.log:

mysqldumpslow -s c -t 10 /var/log/mysql/mysql-slow.log > top10-by-count.log

Percona Toolkit

Еще есть отличный инструмент Percona Toolkit

Для установки нужно использовать

apt-get install percona-toolkit

Запуск анализа по логу

pt-query-digest /var/log/mysql/mysql-query.log > digest.txt

После этого будет сгенерирован достаточно длинный отчет. Сверху будет приведена общая информация о всех медленных запросах:

# Attribute          total     min     max     avg     95%  stddev  median
# ============     ======= ======= ======= ======= ======= ======= =======
# Exec time           634s      1s     54s      4s      8s      6s      2s
# Lock time            7ms       0   953us    48us   167us   151us       0
# Rows sent        107.62M       0   1.52M 720.30k   1.46M 619.39k 462.39k
# Rows examine     107.62M       0   1.52M 720.30k   1.46M 619.38k 462.39k
# Query size        70.38k      45  10.94k  471.04   88.31   1.93k   49.17

Обратите внимание на медианы. В примере — половина всех запросов выполняется дольше 2 секунд — это плохо.

Ниже можно посмотреть общий профиль всех медленных запросов:

# Rank Query ID           Response time  Calls R/Call V/M   Item
# ==== ================== ============== ===== ====== ===== ==============
#    1 0x67A347A2812914DF 440.2687 69.5%   119 3.6997  1.61 SELECT stats_min
#    2 0x0212FEF8C81EF1B6  78.2438 12.3%     8 9.7805 27.12 UPDATE files
#    3 0x2D2411FF42855142  67.4195 10.6%    10 6.7419 33.64 UPDATE projects
#    4 0xE5418AFB28BC18CF  25.1232  4.0%     7 3.5890  2.62 INSERT UPDATE files

Все запросы отсортированы по общему времени выполнения time. Оптимизировать запросы нужно в таком же порядке — это даст наибольший эффект. Кроме этого обратите внимание на колонку R/Call — там указано среднее время выполнения одного запроса. В примере у второго запроса это время больше 9 секунд, следует выяснить причины.

После этого в отчете можно увидеть детальный профиль каждого запроса:

# Query 1: 0.00 QPS, 0.00x concurrency, ID 0x67A347A2812914DF at byte 98907
# Scores: V/M = 1.61
# Time range: 2014-12-12 01:00:40 to 2015-02-03 01:01:22
# Attribute    pct   total     min     max     avg     95%  stddev  median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count         77     119
# Exec time     69    440s      1s      9s      4s      8s      2s      2s
# Lock time      0       0       0       0       0       0       0       0
# Rows sent     99 107.52M   1.19k   1.52M 925.21k   1.46M 565.37k 462.39k
# Rows examine  99 107.52M   1.19k   1.52M 925.21k   1.46M 565.37k 462.39k
# Query size     8   5.68k      46      54   48.89   51.63    1.51   49.17
# String:
# Hosts        localhost
# Users        root
# Query_time distribution
#   1us
#  10us
# 100us
#   1ms
#  10ms
# 100ms
#    1s  ================================================================
#  10s+

# Tables
#    SHOW TABLE STATUS FROM `t` LIKE 'stats_min'\G
#    SHOW CREATE TABLE `t`.`stats_min`\G
SELECT * FROM `stats_min`\G

# Converted for EXPLAIN
# EXPLAIN SELECT * FROM `stats_min`\G

Эти данные покажут детальное распределение ресурсов. Следует обратить внимание на Lock time, Rows sent, Rows examine. Чем больше эти значения, тем хуже.

И еще надо помнить, что в этот лог может попадать и запросы, которые отлично работают. Если сервер был загружен еще какими-то заданиями то запрос может выполняться дольше. После того как получили список запросов нужно анализировать их c помощью EXPLAIN.

Links:

devnotes.com.ua

ruhighload.com

Документация Percona Toolkit

2019-06-08 06:49:00