explain
用一条简单的sql看看使用explain关键字的效果:
explain select * from sys_menu
id列
该列的值是select查询中的序号,比如:1、2、3、4等,它决定了表的执行顺序。
某条sql的执行计划中一般会出现三种情况:
- id相同
- id不同
- id相同和不同都有
那么这三种情况表的执行顺序是怎么样的呢?
id值相同
explain
select
*
from sys_user su
inner join sys_user_role sur
on su.id = sur.user_id
从上到下执行
id不同
explain
select *
from sys_user su
where su.id in (select user_id from sys_user_role sur)
序号大的先执行,这里会从下到上执行,先执行表sur,再执行表su。
id相同和不同都有
explain
select *
from sys_user su
inner join (select max(user_id) mid from sys_user_role sur GROUP BY user_id) t2
on su.id = t2.mid
先执行序号大的,先从下而上执行。遇到序号相同时,再从上而下执行。所以这个列子中表的顺序顺序是:sur、su、
type类型
执行结果从最好到最坏的的顺序是从上到下。
我们需要重点掌握的是下面几种类型:
system > const > eq_ref > ref > range > index > ALL
system
这种类型要求数据库表中只有一条数据,是const类型的一个特例,一般情况下是不会出现的。
const
通过一次索引就能找到数据,一般用于主键或唯一索引作为条件的查询sql
explain
select *
from sys_user where id = 1
eq_ref
常用于主键或唯一索引扫描。执行sql如下:
explain
select *
from sys_user su
inner join sys_user_role sur
on su.id = sur.user_id
ref
常用于非主键和唯一索引扫描。执行sql如下:
range
常用于范围查询,比如:between … and 或 In 等操作,执行sql如下:
index
全索引扫描。执行sql如下:
ALL
全表扫描
possible_keys列
请注意,此列完全独立于表的顺序,这就意味着possible_keys在实践中,某些键可能无法与生成的表顺序一起使用。
如果此列是NULL,则没有相关的索引。在这种情况下,您可以通过检查该WHERE 子句以检查它是否引用了某些适合索引的列,从而提高查询性能。
key列
该列表示实际用到的索引。
可能会出现possible_keys列为NULL,但是key不为NULL的情况。
key_len列
索引长度
该列表示使用索引的长度。上面的key列可以看出有没有使用索引,key_len列则可以更进一步看出索引使用是否充分。不出意外的话,它是最重要的列。
有个关键的问题浮出水面:key_len是如何计算的?
决定key_len值的三个因素:
- 1.字符集
- 2.长度
- 3.是否为空
show processlist
查询执行语句是否还在线程中
若是时间特别长
可以 kill ID
慢查询
慢查询是否开启
show variables like '%slow_query%'
可以临时开启慢查询
SET GLOBAL slow_query_log =1
慢查询日志详情
第一行是代码执行时间;
第二行为ip地址;
第三行分别是①查询执行时间,②获取锁的时间,③返回的行数,④查询遍历扫描的行数,这里因为sql没有条件限制所以相等;
第四行就是mysql查询时间的时间戳(直接看Time也是一样的)
第五行是慢查询的sql语句
查询慢查询时间
show variables like 'long_query_time';
查询mysql所有查询日志
show variables like '%general_log%';
set global general_log=ON;
插入语句
查询语句