数据库索引系列三:EXPLAIN使用详解

explain用于查看一条sql语句如何使用索引来查询以及连接表,旨在帮助我们使用好索引和写出高性能的查询sql。
在这里插入图片描述

举例:

EXPLAIN SELECT s.uid,s.username,s.name,f.email,f.mobile,f.phone,f.postalcode,f.address 
FROM uchome_space AS s,uchome_spacefield AS f 
WHERE 1 
AND s.groupid=0 
AND s.uid=f.uid;

它的执行结果是:
这里写图片描述
下面我们先分析一下sql解析的结果:
1. id

select识别符。这是select查询序列号,并不是sql语句执行的顺序,执行顺序是由引擎决定的。id为null的就表示这是一个结果集,不需要使用它来查询。看下面这条sql:
EXPLAIN SELECT * FROM (SELECT * FROM uchome_space LIMIT 10) AS s;
它的执行结果是:
这里写图片描述
可以看到这时的id变化了。

2. select_type

select类型,它有以下几种值:
2.1 simple:标识简单的sql,没有union和子查询;
2.2 primary:最外面的select,在有子查询的语句中,最外面的select查询就是primary。
2.3 union:union语句第二个或者说是后面那一个。例如:
select * from uchome_space limit 10 union select * from uchome_space limit 10,10;
执行结果如下:
这里写图片描述
2.4 dependent union:union中的第二个或后面的select语句,但是这个查询要依赖于外面的查询;
2.5 union result:union查询的结果;
2.6 derived:from字句中出现的子查询,也叫派生表。
2.7 subquery:除了from字句中包含的子查询外,其他地方出现的子查询都可能是subquery;
2.8 dependent subquery:与dependent union类似,表示这个subquery的查询要收到外部表查询的影响。
EXPLAIN SELECT *,(SELECT a.name FROM user u WHERE u.id=i.userId) as userName FROM info i LIMIT 1;
这里写图片描述
2.9 materialized:物化子查询,不太清楚,a这个值查询出来是null
这里写图片描述

3. table

输出的行所用的表。
3.1 如果查询使用了别名,那么这里显示的是别名;
3.2 如果不涉及对数据表的操作,那么这里显示为null;
3.3 如果显示为< derived N>就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生;
3.4 如果是< union M,N>,也是临时表,表示这个结果来自于union查询的id为M和N的结果集。

4. type

依次从好到差:system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,index_subquery,range,index_merge,index,ALL。除了ALL以外,其他的type都用到了索引,除了index_merge之外,其他的type只可以用到一个索引。
4.1 system:表中只有一行数据或者是空表,且只能用于myisam和memory表。如果是innodb引擎,type通常是ALL或index;
如:这里写图片描述
4.2 const:使用唯一索引或者主键,返回记录一定是一行记录的等值where条件时,通常type是const。其他数据库也叫唯一索引扫描;
这里写图片描述
4.3 eq_ref:出现在要连接多个表的查询计划中,驱动表只返回一行数据,且这行数据是第二个表的主键或唯一索引,且必须为not null。唯一索引和主键是多列时,只有所有的列都用作比较时才会出现eq_ref;如2.8图。
4.4 ref:不像eq_ref那样要求连接顺序,也没有主键和唯一索引的要求,只要使用相等(即“=”符号)条件检索时就可能出现,常见于辅助索引的等值查找。或者多列主键、唯一索引的联合索引中,使用第一个列之外的列作为等值查找也会出现,总之,返回数据不唯一的索引等值查找就有可能出现。
explain select * from uchome_space where uchome_space.friendnum = 0;
这里写图片描述
4.5 fulltext:全文索引检索,要注意,全文索引的优先级很高,若全文索引与普通索引同时存在,MySQL不管代价,优先使用全文索引,全文索引只存在于myisam引擎数据库中。
4.6 ref_or_null:与ref方法类似,只是增加了null值的比较,实际用的不多。
4.7 unique_subquery:用于where中的in形式子查询,子查询返回不重复值唯一值。
4.8 index_subquery:用于in形式子查询使用到了辅助索引子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可使用索引将子查询去重。
4.9 range:索引范围扫描,常见于使用< , > , is null , between, in , like等运算符的查询中。
4.10 index_merge:表示查询使用了两个以上的索引,最后取交集或者并集,常见and,or的条件使用了不同的索引,官方排序这个在ref_or_null之后,但是实际上由于要读取多个索引,性能可能大部分时间不如range。
4.11 index:索引全表扫描,把索引从头到尾扫一遍,常见于使用索引列就可以处理不需要读取数据文件的查询、可以使用索引排序或者分组的查询。
4.12 all:全表扫描数据文件,然后再在server层进行过滤后返回符合要求的数据。

5. possible_keys

查询可能使用到的索引都会在这里列出来

6. keys

查询真正使用到的索引。
注:select_type为index_merge时,这里可能出现两个以上的索引,其他的只有一个。

7. key_len

用于处理查询的索引长度,如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查询不一定都能使用到所有的列,where条件里具体使用到多少个列的索引,这里就会计算进去,没有使用到的列或排序分组使用的索引,这里不会算进去。
这个字段一般只有联合索引时候才有意义,代表你命中了其中的几个索引

8. ref

用来标识那些用来进行索引比较的列或者常量
8.1. 如果是使用的常数等值查询,这里会显示const;
8.2. 如果是子查询,这里显示驱动表关联的列名;
这里写图片描述
8.3. 如果是表连接查询,被驱动表的执行计划这里会显示驱动表的关联字段;
8.4. 如果是条件使用了表达式或者函数,或者条件发生了内部隐式转换,这里可能显示为func;

9. rows

这里是执行计划中估算的扫描行数,不是精确值。

10. extra

这个列可以显示的信息非常多,有几十种,常用的有:
10.1. distinct:在select部分使用了distinct关键字
10.2. no table used:不带from字句的查询或者from dual查询
这里写图片描述
10.3. Using where:表示存储引擎返回的记录并不是所有的都满足条件,需要在server层进行过滤。查询条件中分为限制条件和检查条件,5.6之前,存储引擎只能根据限制条件扫描数据并返回,然后server层根据检查条件进行过滤再返回真正符合查询的数据。5.6.x之后支持ICP特性,可以把检查条件也下推到存储引擎层,不符合检查条件和限制条件的数据,直接不读取,这样就大大减少了存储引擎扫描的记录数量,extra显示using index condition。
这里写图片描述
10.4. using index:查询时不需要回表查询,直接通过索引就可以获取查询的数据
这里写图片描述
10.5. not in/not exists:使用not in()形式子查询或not exist运算符的连接查询,这种叫作反连接。即,一般连接查询是先查询内表,在查询外表,反连接就是先查外表,再查内表。
10.6. using filesort:排序时无法使用到索引时,就会出现这个。常见于order by或group by语句中。
10.7. using join buffer(block nested loop),using join buffer(batched key accss):5.6.x之后的版本优化关联查询的BNL,BKA特性。主要是减少内表的循环数量以及比较顺序地扫描查询。
10.8. using_union:表示使用or的各个索引的条件时,该信息表示从结果集获取并集
using intersect:表示使用and的各个索引的条件时,该信息表示从结果集获取交集
using sort_union,using sort_intersection:与前面两个类似,只是他们是出现在用and和or查询信息量大时,先查询主键,然后进行排序合并后,才能读取记录并返回。
10.9. using temporary:表示使用了临时表存储中间结果,临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看status变量,used_tmp_table,used_temp_disk_table才能看出来。
10.10. firstmatch(tb_name):5.6.x开始引入的优化子查询的新特性之一,常见于where字句含有in()类型的子查询,如果内表数据量比较大,就可能出现这个。
10.11. loosescan(m…n):5.6.x之后引入的优化子查询的新特性之一,在in()类型的子查询中,子查询返回的可能有重复记录时,就可能出现这个。

11. filterred

使用explain extended是会出现这个列,5.7之后的版本默认就有这个列,不需要使用explain extended了。这个字段表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例。 通俗讲就是返回行数在读取行数中所占百分比,这个值越高约好,越高越有意义。
这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在MySQL中,EXPLAIN是一个关键字,用于查询SQL语句的执行计划和索引使用情况。使用EXPLAIN可以帮助我们了解MySQL如何处理我们的查询语句,并对查询进行优化。 EXPLAIN命令会返回一个包含12列信息的结果集。这些列包括:id,select_type,table,partitions,type,possible_keys,key,key_len,ref,rows,filtered,Extra。每一列都提供了有关查询执行的详细信息。 - id列表示查询的标识符,常用来区分查询的不同部分。 - select_type列表示查询的类型,例如简单查询、子查询、联合查询等。 - table列表示与查询相关的表名。 - partitions列表示查询涉及的分区信息。 - type列表示查询的访问类型,包括全表扫描、索引扫描、范围扫描等。 - possible_keys列表示可能用到的索引。 - key列表示实际使用索引。 - key_len列表示索引的长度。 - ref列表示查询中使用索引引用。 - rows列表示查询返回的行数估计值。 - filtered列表示查询结果的过滤率。 - Extra列提供了额外的信息,如是否使用了临时表、是否使用了文件排序等。 通过分析EXPLAIN的结果,我们可以判断查询是否使用索引,是否存在全表扫描等问题,从而进行查询性能的优化。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Mysql的explain详解](https://blog.csdn.net/weixin_44143114/article/details/118526637)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [MySQL数据库:第十七章:Explain详解](https://blog.csdn.net/java_wxid/article/details/111881486)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值