mysql慢查询 + explain使用及返回的参数详解

一、mysql慢查询

(1)慢查询参数说明

slow_query_log 慢查询开启状态
slow_query_log_file 慢查询日志存放的位置(这个目录需要MySQL的运行帐号的可写权限,一般设置为MySQL的数据存放目录)
long_query_time 查询超过多少秒才记录
log_queries_not_using_indexes 设置为ON时,可以捕获到所有未使用索引的SQL语句

(2)查看慢查询参数状态

mysql> show global variables like 'slow_query%';

+---------------------+---------------------------------------------------+
| Variable_name       | Value                                             |
+---------------------+---------------------------------------------------+
| slow_query_log      | ON                                                |
| slow_query_log_file | /usr/local/var/mysql/xiafendeMacBook-Pro-slow.log |

+---------------------+---------------------------------------------------+

mysql> show global variables like 'long_query_time';
+-----------------+----------+
| Variable_name   | Value    |
+-----------------+----------+
| long_query_time | 1.000000 |

+-----------------+----------+

(3)修改慢查询参数

(3.1)方法一:临时设置(重启mysql就失效了)

mysql> set global slow_query_log='ON'; //将slow_query_log全局变量设置为“ON”状态 
mysql> set global slow_query_log_file='/usr/local/mysql/data/slow.log'; //设置慢查询日志存放的位置
mysql> set global long_query_time=1; //查询超过1秒就记录
mysql> exit; //exit后再次登录mysql进来,就生效了

(3.2)方法二:永久设置: 配置文件设置my.ini或my.cnf(window中mysql的配置文件my.ini,mac和linux中是my.cnf)

[mysqld]
slow_query_log = ON
slow_query_log_file = /usr/local/mysql/data/slow.log
long_query_time = 1

然后重启mysql: service mysqld restart

(4)Mysql的日志记录方法迅速查找具体SQL

页面打开速度极慢的情况,通过排除,确定了,是数据库的影响,为了迅速查找具体的SQL,可以通过Mysql的日志记录方法。

-- 打开sql执行记录功能
set global log_output='TABLE'; -- 输出到表
set global log=ON; -- 打开所有命令执行记录功能general_log, 所有语句: 成功和未成功的.
set global log_slow_queries=ON; -- 打开慢查询sql记录slow_log, 执行成功的: 慢查询语句和未使用索引的语句
set global long_query_time=0.1; -- 慢查询时间限制(秒)
set global log_queries_not_using_indexes=ON; -- 记录未使用索引的sql语句

-- 查询sql执行记录
select * from mysql.slow_log order by 1; -- 执行成功的:慢查询语句,和未使用索引的语句
select * from mysql.general_log order by 1; -- 所有语句: 成功和未成功的.

-- 关闭sql执行记录
set global log=OFF;
set global log_slow_queries=OFF;
-- long_query_time参数说明
-- v4.0, 4.1, 5.0, v5.1 到 5.1.20(包括):不支持毫秒级别的慢查询分析(支持精度为1-10秒);
-- 5.1.21及以后版本 :支持毫秒级别的慢查询分析, 如0.1;
-- 6.0 到 6.0.3: 不支持毫秒级别的慢查询分析(支持精度为1-10秒);

-- 6.0.4及以后:支持毫秒级别的慢查询分析;


二、explain使用及参数详解

(1)explain的使用:explain  + sql查询语句

(2)使用explain后返回的8个参数

(2.1)8个参数详解

强烈推荐这篇文章讲单列和联合索引,对照下面4个标红的重要参数来理解:
https://blog.csdn.net/abysscarry/article/details/80792876

参数 参数说明
table 显示这一行的数据是关于哪张表的
type 这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL
possible_keys 显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从WHERE语句中选择一个合适的语句
key

实际使用的索引。如果为NULL,则没有使用索引。很少的情况下,MYSQL会选择优化不足的索引。这种情况下,

可以在SELECT语句 中使用USE INDEX(indexname)来强制使用一个索引或者

用IGNORE INDEX(indexname)来强制MYSQL忽略索引

key_len 使用的索引的长度。在不损失精确性的情况下,长度越短越好
ref 显示索引的哪一列被使用了,如果可能的话,是一个常数
rows

MYSQL认为必须检查的用来返回请求数据的行数,不是返回结果的行数,此值比返回结果的行数要多。此值越少越好??

Extra

关于MYSQL如何解析查询的额外信息。将在表4.3中讨论,但这里可以看到的坏的例子是Using temporary和Using filesort,意

思MYSQL根本不能使用索引,结果是检索会很慢,看到这两个的时候,就意味着查询需要优化了

关于rows,在不加任何索引的情况下,验证rows比返回结果的行数要多




(2.2)type详解

(http://blog.51cto.com/lijianjun/1881208 详解all、index、range、ref、eq_ref

从最好到最差的连接类型为const、eq_reg、ref、range、index、ALL)

类型 含义
system 表只有一行
const 表最多只有一行匹配,通用用于主键或者唯一索引比较时
eq_ref

每次与之前的表合并行都只在该表读取一行,这是除了system,const之外最好的一种,特点是使用=,而且索引的所有部分都参与join且索引是主键或非空唯一键的索引

ref 如果每次只匹配少数行,那就是比较好的一种,使用=或<=>,可以是左覆盖索引或非主键或非唯一键
fulltext 全文搜索
ref_or_null 与ref类似,但包括NULL
index_merge

表示出现了索引合并优化(包括交集,并集以及交集之间的并集),但不包括跨表和全文索引。

这个比较复杂,目前的理解是合并单表的范围索引扫描(如果成本估算比普通的range要更优的话

unique_subquery

在in子查询中,就是value in (select...)把形如“select unique_key_column”的子查询替换。

PS:所以不一定in子句中使用子查询就是低效的!

index_subquery 同上,但把形如”select non_unique_key_column“的子查询替换
range  常数值的范围
index

a.当查询是索引覆盖的,即所有数据均可从索引树获取的时候(Extra中有Using Index);

b.以索引顺序从索引中查找数据行的全表扫描(无 Using Index);

c.如果Extra中Using Index与Using Where同时出现的话,则是利用索引查找键值的意思;

d.如单独出现,则是用读索引来代替读行,但不用于查找

all 全表扫描

(2.3)Extra详解

参数 参数说明
Distinct 一旦MYSQL找到了与行相联合匹配的行,就不再搜索了
Not exists MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就不再搜索了
Range checked for each Record(index map:#) 没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一
Using filesort 看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行
Using index 列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候
Using temporary 看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上
Where used 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题不同连接类型的解释(按照效率高低的顺序排序)
const 表中的一个记录的最大值能够匹配这个查询(索引可以是主键或惟一索引)。因为只有一行,这个值实际就是常数,因为MYSQL先读这个值然后把它当做常数来对待
eq_ref 在连接中,MYSQL在查询时,从前面的表中,对每一个记录的联合都从表中读取一个记录,它在查询使用了索引为主键或惟一键的全部时使用

ref

这个连接类型只有在查询使用了不是惟一或主键的键或者是这些类型的部分(比如,利用最左边前缀)时发生。对于之前的表的每一个行联合,全部记录都将从表中读出。这个类型严重依赖于根据索引匹配的记录多少—越少越好
range 这个连接类型使用索引返回一个范围中的行,比如使用>或<查找东西时发生的情况
index 这个连接类型对前面的表中的每一个记录联合进行完全扫描(比ALL更好,因为索引一般小于表数据)
ALL 这个连接类型对于前面的每一个记录联合进行完全扫描,这一般比较糟糕,应该尽量避免

参考:https://www.cnblogs.com/qmfsun/p/4844472.html

https://blog.csdn.net/qh_java/article/details/71247224

http://blog.51cto.com/lijianjun/1881208

猜你喜欢

转载自blog.csdn.net/wuhuagu_wuhuaguo/article/details/80625124