mysql慢查询日志和执行计划

什么是慢查询日志

慢查询日志是MySQL提供的一种日志记录,它记录了在查询过程中性能不好的SQL语句,我们可以设置long_query_time的值,当SQL语句的执行时间超过设置的long_query_time值时,这条语句就会被记录在慢查询日志中。Mysql数据库默认关闭了慢查询日志,需要我们手动开启。慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表。

为什么要开启慢查询日志

慢查询日志可以跟踪有问题的查询语句,通过分析慢查询日志我们可以知道哪些SQL语句执行的效率低下,以便对SQL语句进行相应的优化。

慢查询日志相关参数

log_output:指定日志存储方式,默认值是’FILE’。表示将日志存入文件,'TABLE’表示将日志存入mysql.slow_log表中。
long_query_time:慢查询阈值时间,当查询时间大于阈值时记录日志。
slow_query_log:慢查询日志状态,OFF表示关闭,ON表示开启。
slow-query-log-file:慢查询日志存储路径。
log_queries_not_using_indexes:ON表示使用索引的查询也记录,OFF表示关闭。

开启慢查询日志

我的mysql版本为8.0.18

select @@version;

在这里插入图片描述
查看是否开启了慢查询日志

show variables like 'slow_query_log';

在这里插入图片描述
看到slow_query_logOFF状态,也就是没有开启慢查询日志。
查看慢查询日志阈值

 show variables like 'long_query_time';

在这里插入图片描述
默认设置的是十秒,为了演示方便,将它设置为0
这里设置后再次查看还是没有变换,需要重新打开一个会话!!!

set global long_query_time=0;

记录未使用索引的查询

set global log_queries_not_using_indexes=on;

查看日志存储位置

 show variables like 'slow_query_log_file';

在这里插入图片描述
开启慢查询日志

 set global slow_query_log=on;

开启后执行两条操作

use class_db;
select * from student;

然后查看慢查询日志,可以看到这两条语句和对应详细信息都被记录下来了。

# Time: 2020-05-24T05:38:48.128651Z
# User@Host: root[root] @ localhost [::1]  Id:     9
# Query_time: 0.000397  Lock_time: 0.000235 Rows_sent: 1  Rows_examined: 1
use class_db;
SET timestamp=1590298728;
# administrator command: Init DB;
# Time: 2020-05-24T05:38:53.243733Z
# User@Host: root[root] @ localhost [::1]  Id:     9
# Query_time: 0.151562  Lock_time: 0.001904 Rows_sent: 7  Rows_examined: 7
SET timestamp=1590298733;
select * from student;

慢查询日志包含的内容:

执行SQL的主机信息
#User@Host: root[root] @ localhost [::1] Id: 9
SQL执行信息
#Query_time: 0.151562 Lock_time: 0.001904 Rows_sent: 7 Rows_examined: 7
SQL执行时间戳
SET timestamp=1590298733;
SQL内容
select * from student;

日志分析工具

在生产环境中,一般会产生大量的慢查询日志记录,手工一条一条地分析日志明显是不现实的,这时候呢就需要用到日志分析工具了,常用的日志分析工具一般有以下两种:

  1. mysqldumpslow
  2. pt-query-digest
    至于日志分析工具的使用这里就不过多介绍了,大家感兴趣的可以去查查文档。

什么是执行计划

执行计划简单来说呢就是SQL在执行时的过程和表现情况,Mysql提供了explain关键字来模拟执行SQL语句,输出执行计划,通过执行计划可以分析查询语句和表结构的性能瓶颈。

首先我们查看表的结构

desc student;

在这里插入图片描述
这张表是ID为主键索引,name为普通索引。
输出一条SQL的执行计划

explain select * from student;

在这里插入图片描述

explain输出解释

  • id: select 的序列号
  • select_type:表示对应行是是简单还是复杂的查询
    1. simple:简单查询。查询不包含子查询和union
    2. primary:复杂查询中最外层的查询
    3. subquery:包含在 select 中的子查询(where子句中)
    4. derived:包含在 from 子句中的子查询。
    5. union:在 union 中的第二个和随后的 select
    6. union result:从 union 表获取结果的 select
  • table:当前SQL访问的表
  • type:连接类型,性能最好到最差分别为(const > eq_ref > ref > range > index > ALL)
    1. const:通过索引一次命中,匹配一行数据,用于 primary key 或 unique key 的所有列与常数比较时
    2. eq_ref:唯一性索引,对于每个索引键,表中只有一条记录与之匹配,常用语主键或唯一索引扫描
    3. ref:普通索引
    4. range:只检索给定范围的行,使用一个索引来选择行
    5. index:只遍历索引树
    6. ALL:全表扫描
  • possible_keys:显示查询可能使用的索引
  • key:实际使用的索引
  • key_len:使用的索引的长度
  • ref :显示索引的那一列被使用
  • rows:找到所需的记录读取的行数
  • Extra:额外信息
    1. Using filesort:mysql对数据使用一个外部的索引排序,而不是按照表内 的索引进行排序读取。
    2. Using temporary:使用了临时表保存中间结果。
    3. Using index:表示 SQL 操作中使用了覆盖索引,避免了访问表的数据行,效率高。
    4. Using where:使用了 where 过滤条件。
    5. Using join buffer :使用了关联查询或者子查询,且需要进行嵌套循环计算。

通常来说当出现了第一项和第二项额外信息时我们就需要对SQL语句进行优化了。

主键查询,type为const

explain select * from student where id=5;

在这里插入图片描述
普通索引查询,type为ref

explain select * from student where name='zack';

在这里插入图片描述
主键范围查询,type为range

explain select * from student where id>2 and id<10;

在这里插入图片描述
普通字段查询,type为ALL(全表扫描,效率最低)

explain select * from student where age=21;

在这里插入图片描述

数据库的优化方案还有很多,执行计划和慢查询日志都可以帮助我们分析优化SQL语句,构建更加合适的表结构,今天的分享就到这里了,希望大家能够有所收获。

猜你喜欢

转载自blog.csdn.net/weixin_42494845/article/details/106312837