Explain
定义
查看当前查询语句索引是否生效,是否有使用到索引
作用
表的读取顺序
查询类型
哪些索引可以使用
哪些索引实际被使用到
简单介绍一下每个字段对应代表什么意思
Explain 每个字段定义
Id
表示查询中执行selet子句或操作表的顺序
select_type
查询的类型,主要是用于区别普通查询、联合查询、子查询等复杂查询
具体有一下几种类型
- SIMPLE 简单的select 查询,查询总不包含子查询或UNION
- PRIMARY 查询中包含任何复杂的子部分,最外层查询则被标记为(主查询)
- SUBQUERY 在select 或where列表中包含了子查询
- DERIVED 在from列表汇总包含的子查询被标记为DERIVED(衍生)
- MySQL会递归执行这些子查询,把结果放在临时表(衍生的临时表)
- UNION 若第二个select出现在UNION之后,则被标记为UNION
- 若UNION包含在form子句的子查询中,外层select将被标记为DERIVED
- UNIONRESULT 从UNION表获取结果的SELECT
table
显示这行数据是关于当前这张表的
type
显示访问类型
结果值从最好到最坏依次是:
system>const>eq_ref>ref>reange>index>ALL
一般来说,保证查询至少达到range级别,最好能达到ref
possible_keys
显示可能应用到这张表中的索引,一个或多个显示可能应用到这张表中的索引,一个或多个;
查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用(理论上应该用到的索引数量);
key
实际使用的索引。如果为NULL,则没有使用索引;
查询中若使用了覆盖索引,则该索引仅出现在key列表中(实际用到的索引数量);
key_len
表示索引中使用的字节数,值越大查询数来的结果越精确
ref
显示索引的哪一列 被使用了,如果可能得话,是一个常数,哪些列或常量被用于查找索引列上的值
rows
根据表统计信息及索引选用情况,大致估算找到所需的记录锁需要读取的行数
Extra
Mysql支持两种排序方式
文件排序(using filesort)或者扫描有序索引排序(using index)
应用场景
场景一
explain select * from student
根据上面的各个字段定义,可以看到这条SQL执行后,select_type显示为是一条简单SQL,table显示为查询的是student表
type 扫描类型是全局扫描,possible_keys 应该用到索引,显示为null,key实际用到索引显示为null,从这两个字段可以看
出,要么索引失效了,要么没有索引,ref也显示到了没有用到索引,Extra 排序类型也没有
查了一下这个表是有索引的,那为什么没有用上呢?
原因是:我在我的博文中(链接: MySQL 索引)提到过索引失效的几种原因,其中就有一种检索数据时使用select *,会导致索引失效,下面我们来验证一下不用select * 是否可以
下面我们来验证一下不用select * ,用索引列是否可以
看到了吧,type是index (system>const>eq_ref>ref>reange>index>ALL),虽然说没有达到ref或reange,但是最起码不是全表扫描ALL,key实际用到索引了,排序类型是 Using index 索引排序,这就是我们一个基本的SQL调优排查,为其排查索引是否失效
场景二
explain select StudentName from student where StudentNo > 'S001' and StudentNo < 'S005' order by StudentNo,StudentName
虽然说查询结果中显示使用了索引,但是在Extra排序中是Using filesort(文件排序),这样对于我们检索来说,也会出现性能损耗的情况,我在我的博文中(链接: MySQL 索引)提到过索引失效的几种原因,其中就有一种 检索数据时使用范围条件进行检索可能会导致索引失效
场景三
explain select a.StudentNo,a.StudentName,b.name from student a left join class b on a.Id = b.student_Id
这种情况我在我的博文中(链接: MySQL 索引)提到过
当在连接多表查询时,如何正确的使用索引
左连接查询将索引建到右边;(LEFT JOIN 条件用于确定如何从右表搜索行,左边一定都有)
右连接查询将索引建到左边;
在这里就向别名为b表中添加索引
--向class表中name字段添加索引 create index name_index on class(name)
这时在看索引就用上了
以上就是Explain的三种使用情况,当然这些都是比较简单的索引问题排查,复杂的也与上面差不多,只要是掌握Explain每个字段的定义,SQL调优以及Explain问题排查就会轻松很多