Mysql 慢查询日志 分析篇

前言

有时我们会发现网站访问十分缓慢甚至于卡死,那么有哪些原因会导致这个问题呢?

  • MySQL 语句没有进行优化,数据库的读写耗费了大量的时间
  • 可能访问的网页中存在调用远程(第三方)接口的业务,远程接口返回特别慢
  • 大量的访问请求导致带宽撑满
  • 服务器负载过大忙不过来,比如说 CPU 和内存消耗完了
  • 本地网络波动
    很多情况下经过排查我们会发现导致网站访问慢的原因在于数据库瓶颈,下面我们来讲讲对应数据库中的慢查询导致的访问慢这种情况如何排查和解决。

什么是慢查询日志

MySQL的慢查询日志是 MySQL 提供的一种日志记录,它用来记录在 MySQL 中响应时间超过阀值的语句,具体指运行时间超过 long_query_time 值的 SQL,则会被记录到慢查询日志中。
所以通过慢查询日志,我们就可以知道到底哪些 sql 语句导致了网页响应速度慢,再根据这些 sql 语句找到哪些具体的业务场景的响应速度特别慢,从而做出响应的优化和调整。
官方 slow_query_log 文档

开启慢查询日志

在开启慢查询日志前,我们要先查看 mysql 对慢查询日志的配置:

show variables  like '%slow_query_log%';

慢查询配置中的各个字段解释:

列名说明
slow_query_log是否开启慢查询日志,1表示开启,0表示关闭。
slow_query_log_fileMySQL数据库慢查询日志存储路径。
long_query_time慢查询阈值,当查询时间多于设定的阈值时,记录日志。
log_queries_not_using_indexes未使用索引的查询也被记录到慢查询日志中(可选项)
log_output日志存储方式 log_output=’FILE’表示将日志存入文件,默认值是’FILE’

注意 long_query_time: 一般我们对慢查询进行优化的时候,会逐步减小这个值(3s->2s->1s),每次减小后观察慢查询日志的情况来调优,以做到尽可能的优化数据库查询速度

开启慢查询的有两种方式:

  1. 临时性,mysql 中输入如下命令,重启 mysql 后会失效
set global slow_query_log=1;
  1. 修改 my.cnf 文件,需要重启 mysql 才能生效
    (查看mysql启动时读取配置文件的默认目录 mysql --help|grep ‘my.cnf’)
    修改配置文件中的如下字段后,重启mysql。
slow_query_log =1
slow_query_log_file=/tmp/mysql_slow.log
long_query_time = 3

当 mysql 服务在线上运行时无法重启时,可以采用第一种方式。

慢查询分析

正所谓工欲善其事必先利其器,在进行慢查询的分析和优化之前,我们要先学习两个分析工具。

日志分析工具 pt-query-digest

开启慢查询日志后,数据会记录在 slow_query_log_file 配置的文件中。 产生的 slow_query_log 原始数据,推荐使用 pt-query-digest 进行分析。

pt-query-digest 是用于分析 mysql 慢查询的一个工具,它可以分析 binlog、General log、slowlog,也可以通过 SHOWPROCESSLIST 或者通过 tcpdump 抓取的 MySQL 协议数据来进行分析。可以把分析结果输出到文件中,分析过程是先对查询语句的条件进行参数化,然后对参数化以后的查询进行分组统计,统计出各查询的执行时间、次数、占比等,可以借助分析结果找出问题进行优化。

pt-query-digest简介

pt-query-digest 的安装

#mac
brew install percona-toolkit

#ubuntu
sudo apt-get install percona-toolkit

#执行完上面后,执行下面
wget http://www.percona.com/downloads/percona-toolkit/2.2.4/percona-toolkit-2.2.4.tar.gz
tar percona-toolkit-2.2.4.tar.gz
cd percona-toolkit-2.2.4
perl Makefile.PL
make && make install

官方安装方法

pt-query-digest 的使用

这里只介绍最基本的用法
在终端输入:

pt-query-digest slow.log > slow_log_reports

该命令将slow_log 中的数据分析后导入至 slow_log_reports
pt-query-digest文档

pt-query-digest结果分析

使用 pt-query-digest 进行分析之后,生成的表报分为两部分: - 首先展示总体的慢查询情况,包括慢查询的总体时间和数量,慢查询语句的分布和排行

# Attribute       total   min    max    avg     95%  stddev  median
# ============   ====== ===== ====== ====== ======= ======= =======
# Exec time        715s    2s    15s     3s      8s      2s      3s
# Lock time        16ms  35us  955us   78us   125us    71us    63us
# Rows sent       1.06k     1     30   5.29    9.83    5.19    0.99
# Rows examine  305.79M 3.47k  2.65M  1.48M   2.62M   1.27M   2.62M
# Query size     60.05k    61 15.72k 298.50  234.30   1.07k  212.52

# Profile
# Rank Query ID                     Response time Calls R/Call V/M   I
# ==== ============================ ============== ==== ====== ===== =
#    1 0x14E439779C808EC504E181181D 400.4732 56.0%   84 4.7675 1.64 SELECT status
#    2 0x304061A22C6FD43505EA5E3A15 263.8186 36.9%  108 2.4428 0.05 SELECT course_lesson_learn
#    3 0xF3B5D5C8166183BAC01523D6C6  10.3960  1.5%    4 2.5990 0.04 SELECT testpaper_result
#    4 0x11B5BFA8FE52965EF9687FFB28   8.4920  1.2%    2 4.2460 0.11 SELECT course_lesson_learn
# MISC 0xMISC                        31.5240  4.4%    8 3.9405  0.0 <7 ITEMS>
total:总计
min:最小
max:最大
avg:平均
95%:95%的查询时间,重点分析
median:中位数,把所有值从小到大排列,位置位于中间那个数

其次展示具体语句的时间分布:

# Attribut   pct   total     min   max     avg     95%  stddev  median
# ========== === ======= ======= ===== ======= ======= ======= =======
# Count       40      84
# Exec time   56    400s      2s   15s      5s     10s      3s      4s
# Lock time   31     5ms    35us 128us    60us    93us    18us    54us
# Rows sent   77     840      10    10      10      10       0      10
# Rows examine 0   1.74M   3.47k 74.54k  21.20k  44.45k  14.13k  17.59k
# Query size  25  15.61k     144   249  190.31  223.14   26.46  183.58
# String:
# Databases    edusoho
# Hosts        172.17.75.2
# Users        esuser
# Query_time distribution
#   1us
#  10us
# 100us
#   1ms
#  10ms
# 100ms
#    1s  ###########################################################
#  10s+  ####
# Tables
#    SHOW TABLE STATUS FROM `edusoho` LIKE 'status'\G
#    SHOW CREATE TABLE `edusoho`.`status`\G
# EXPLAIN /*!50100 PARTITIONS*/

日志分析工具 Explain命令

MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性优化。所以我们需要先了解 explain 命令的使用及相关参数说明。

#usage
explain SELECT * FROM testpaper WHERE target IN ('course-7169','course-7101')\G;

#result
           id: 1
  select_type: SIMPLE
        table: testpaper
   partitions: NULL
         type: range
possible_keys: target
          key: target
      key_len: 92
          ref: NULL
         rows: 38
     filtered: 100.00
        Extra: Using where
1 row in set, 1 warning (0.00 sec)
列名说明
select_type显示本行是简单或复杂 select。如果查询有任何复杂的子查询,则最外层标记为 PRIMARY
table访问引用哪个表
type数据访问/读取操作类型(ALL、index、range、ref、eq_ref、const/system、NULL)
possible_keys揭示哪一些索引可能有利于高效的查找
key显示 mysql 决定采用哪个索引来优化查询
key_len显示 mysql 在索引里使用的字节数
ref显示了之前的表在 key 列记录的索引中查找值所用的列或常量
rows为了找到所需的行而需要读取的行数,估算值,不精确

上表对每个 explain 结果的每个字段作了大致说明,下面我们详细讲讲实际分析中部分字段的作用。

  • type:指访问类型,是一个比较重要的指标。
  1. ALL :查询的最差情况,说明数据库通过扫描全表的方式得出了结果。在数据量十分庞大时需要的时间很高
  2. index:按照索引次序进行的全表扫描,避免了排序的开销。
  3. range:在一个范围内的索引扫描。
  4. ref:一种索引扫描,它返回所有匹配某个单个值的行。
  5. eq_ref:使用唯一性索引或主键查找,最多只返回一条符合条件的记录。
  6. const:当确定最多只会有一行匹配的时候,MySQL优化器会在查询前读取它而且只读取一次,因此非常快

结果值从好到坏依次是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL ,一般来说,得保证查询至少达到 range 级别,最好能达到 ref。

  • key:显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。
  • key_len:显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。使用的索引的长度。在不损失精确性的情况下,长度越短越好 。
  • Extra:显示MySQL在查询过程中的一些详细信息,MySQL查询优化器执行查询的过程中对查询计划的重要补充信息。
  1. Using filesort:通过索引生成了有序的结果
  2. Using temporary:用临时表保存中间结果,常用于GROUP BY 和 ORDER BY操作中,一般看到它说明查询需要优化了
  3. Using index:说明查询是覆盖了索引的,不需要读取数据文件,从索引树(索引文件)中即可获得信息。如果同时出现using where,表明索引被用来执行索引键值的查找,没有using where,表明索引用来读取数据而非执行查找动作。这是MySQL服务层完成的,但无需再回表查询记录。
  4. Using where:使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。注意:Extra列出现Using where表示MySQL服务器将存储引擎返回服务层以后再应用WHERE条件过滤。

explain详细介绍

上一篇 浅谈Scrum(一)-- 什么是Scrum?
下一篇 Mysql 慢查询日志 优化篇

EduSoho官网 https://www.edusoho.com/
EduSoho开源地址 https://github.com/edusoho/edusoho
我们正在寻找开发者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值