MySQL中主要有4种方式可以分析数据库性能,分别是慢查询日记,profile,Com_xxx和explain。
慢查询日记
先用下面下令查询慢查询日记是否开启,- show variables like 'slow_query_log';
- # 一般默认都是以下结果
- +----------------+-------+
- | Variable_name | Value |
- +----------------+-------+
- | slow_query_log | OFF |
- +----------------+-------+
复制代码
- 若效果为 ON,表示慢查询日记已开启;若为 OFF,则需要手动开启。但是一样平常慢查询日记是默认不开启的,需要手动开启,因为需要指定指标,也就是多慢的SQL才算慢SQL。
暂时开启(重启 MySQL 后失效):- # 开启慢查询日志
- set global slow_query_log = 'ON';
- # 设置一个时间,超过这个时间的查询都会被认为是慢查询,会记录到慢查询日志里,单位是秒(s)
- set global long_query_time = 2;
复制代码 永久开启:
linux环境下只需要改一下/etc/my.cnf设置文件,在里面加入如下两行设置- # 0:关闭慢查询日志 1:开启慢查询日志
- slow_query_log = 1
- # 指定日志文件路径(可选,不选则有默认路径)
- slow_query_log_file = /var/log/mysql/slow.log
- # 设置一个时间,超过这个时间的查询都会被认为是慢查询,会记录到慢查询日志里,单位是秒(s)
- long_query_time = 2
- # 是否记录未使用索引的查询(1表示开启,0表示关闭,默认关闭)
- log_queries_not_using_indexes = 1
复制代码 关键是参数【slow_query_log】和【long_query_time】一定要设置,设置完毕生存后然后使用【systemctl restart mysqld】在Linux下令行重启MySQL即可。此时慢查询的日记会记录到文件里,如果没有设置路径,使用到了默认路径,可以查询一下文件位置:- SHOW VARIABLES LIKE 'slow_query_log_file';
- # 得到结果可能如下
- +---------------------+-------------------------------+
- | Variable_name | Value |
- +---------------------+-------------------------------+
- | slow_query_log_file | /var/lib/mysql/hostname-slow.log |
- +---------------------+-------------------------------+
复制代码 然后去指定目录直接检察log文件即可。
profile
使用下列下令检察profiling是否开启- show variables like 'profiling';
- # 默认是关闭的,一般查询结果如下
- +---------------+-------+
- | Variable_name | Value |
- +---------------+-------+
- | profiling | OFF |
- +---------------+-------+
复制代码 需要手动开启。
暂时开启profiling(重启 MySQL 后失效):
在SQL执行窗口设定参数永久开启:
在/etc/my.cnf文件中加入如下设置要记得修改过/etc/my.cnf文件以后要重启mysql。
此时任意执行几条sql,然后再来查询一下profile。- # 此时为了测试我创建了一个表
- # 执行下面几条查询
- select * from test where id = 2;
- select * from test where id = 1;
- select * from test;
- # 执行下行语句,查询Query记录
- show profiles;
- # 得到如下结果,Query列是查询语句,Duration是执行消耗的时间,Query_ID是记录ID
- +----------+------------+------------------------------------+
- | Query_ID | Duration | Query |
- +----------+------------+------------------------------------+
- | 1 | 0.00029275 | select * from test where id = 2 |
- | 2 | 0.00022375 | select * from test where id = 1 |
- | 3 | 0.00020425 | select * from test |
- +----------+------------+------------------------------------+
- # 如果想要对某一条SQL进行分析,比如这里Query_ID为1的记录消耗时间最长,想要看一下具体情况,可以使用如下命令
- show profile for query 1;
- # 得到如下结果
- +--------------------------------+----------+
- | Status | Duration |
- +--------------------------------+----------+
- | starting | 0.000115 |
- | Executing hook on transaction | 0.000008 |
- | starting | 0.000009 |
- | checking permissions | 0.000005 |
- | Opening tables | 0.000037 |
- | init | 0.000004 |
- | System lock | 0.000007 |
- | optimizing | 0.000009 |
- | statistics | 0.000045 |
- | preparing | 0.000011 |
- | executing | 0.000009 |
- | end | 0.000002 |
- | query end | 0.000002 |
- | waiting for handler commit | 0.000007 |
- | closing tables | 0.000007 |
- | freeing items | 0.000010 |
- | cleaning up | 0.000007 |
- +--------------------------------+----------+
- # 可以看到开始时间,执行时间,打开表的时间,优化时间,准备时间,关闭表的时间等参数
- # 如果SQL查询很慢的话则可以从这里分析原因
复制代码 Com_%
在需要分析增删改查操纵到底是增删改比较多还是查询比较多的时候可以使用这个方式查询相干记录的执行情况,分析某个业务到底是查询比较多呢还是更新比较多,从而可以更好地对体系架构举行把控。
explain
- # 对需要执行的sql分析执行计划,假如要分析下面这条查询语句
- select * from tb_user where id=1;
- # 语法如下
- explain select * from test where id=1;
- # 其实就是在查询语句前加上explain关键字,insert,update和delete语句前也可以加上进行分析执行计划
- # 得到结果格式如下
- +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
- | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
- +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
- | 1 | SIMPLE | tb_user | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL |
- +----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
- # 需要关注id列
- # 相同的 id 表示同一查询块。
- # id 越大,执行优先级越高。
- # id 为 NULL 表示是 UNION 结果的合并操作。
- # -----------------------------------------------------
- # 需要关注type列,其中type列的介绍和性能如下(性能从高到低排列)
- # NULL:直接查询,不进行表操作,例如select 1 + 1;
- # system:表中只有一行数据(系统表)。
- # const:通过主键或唯一索引查找一行数据。
- # eq_ref:通过唯一索引关联表(多表 JOIN 时,每行只匹配一行)。
- # ref:通过非唯一索引查找数据。
- # range:使用索引范围扫描。
- # index:全索引扫描(扫描索引树,不访问数据行)。
- # ALL:全表扫描(性能最差)。
- # -----------------------------------------------------
- # 需要关注possible_keys列和key列
- # possible_keys代表可能用到的索引,key就是实际用到的索引,从这里可以分析索引是不是没有用到或者失效了
- # 优化的时候要尽量让没有使用到索引的语句使用索引
- # -----------------------------------------------------
- # 需要关注key_len
- # 如果用到了单列索引,则key_len是一个固定值
- # 如果用到了联合索引,key_len的值可能会因为部分索引失效而导致key_len的值不一样,可以通过这一列判断联合索引是否全部生效。
- # -----------------------------------------------------
- # 需要关注rows列,记录的是MySQL预估需要扫描的行数。
- # 行数越少,性能越好,如果值很大,可能需要优化索引或查询条件。
- # -----------------------------------------------------
- # 需要关注filtered列
- # filtered= Server层过滤后的行数/存储引擎层返回的行数 ×100%
- # 值越小,说明存储引擎层已经过滤了更多不满足条件的数据,Server 层只需处理少量数据。
- # -----------------------------------------------------
- # 重点关注Extra列,其中可能出现的值如下:
- # Using where:使用了 WHERE 条件过滤数据。
- # Using index:使用了覆盖索引(无需回表)。
- # Using temporary:使用了临时表(性能较差)。
- # Using filesort:使用了文件排序(性能较差)。
- # Using join buffer:使用了 JOIN 缓冲区(多表 JOIN 时)。
- # Impossible WHERE:WHERE 条件永远为假(无结果)。
- # 需要注意尽可能避免Using temporary和Using filesort,以及Impossible WHERE。
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |