explain | 索引优化的这把绝世好剑,你真的会用吗?(下)

简介: explain | 索引优化的这把绝世好剑,你真的会用吗?(下)

正文


explain详解


key列


该列表示实际用到的索引。

可能会出现possible_keys列为NULL,但是key不为NULL的情况。


演示之前,先看看test1表结构:

1.png


test1表中数据:

2.png


使用的索引:

3.png


code和name字段使用了联合索引。

执行sql如下

explain select code  from test1;

结果:

4.png


这条sql预计没有使用索引,但是实际上使用了全索引扫描方式的索引。


key_len列


该列表示使用索引的长度。上面的key列可以看出有没有使用索引,key_len列则可以更进一步看出索引使用是否充分。不出意外的话,它是最重要的列。

5.png


有个关键的问题浮出水面:key_len是如何计算的?


决定key_len值的三个因素

 1.字符集

 2.长度

 3.是否为空


常用的字符编码占用字节数量如下:

6.png

目前我的数据库字符编码格式用的:UTF8占3个字节。


mysql常用字段占用字节数:

字段类型 占用字节数
char(n) n
varchar(n)  n + 2
tinyint 1
smallint 2
int 4
bigint 8
date 3
timestamp 4
datetime 8


此外,如果字段类型允许为空则加1个字节。


上图中的 184是怎么算的?


184 = 30 * 3 + 2 + 30 * 3 + 2


 再把test1表的code字段类型改成char,并且改成允许为空:

7.png

执行sql如下

explain select code  from test1;

结果:

8.png

怎么算的?

183 = 30 * 3 + 1 + 30 * 3 + 2


还有一个问题:为什么这列表示索引使用是否充分呢,还有使用不充分的情况?

执行sql如下


explain select code  from test1 where code='001';

结果:


9.png

上图中使用了联合索引:idx_code_name,如果索引全匹配key_len应该是183,但实际上却是92,这就说明没有使用所有的索引,索引使用不充分。


ref列


该列表示索引命中的列或者常量。

执行sql如下

explain select *  from test1 t1 inner join test1 t2 on t1.id=t2.id where t1.code='001';

结果:

10.png

我们看到表t1命中的索引是const(常量),而t2命中的索引是列sue库的t1表的id字段。


rows列


该列表示MySQL认为执行查询必须检查的行数。

11.png

对于InnoDB表,此数字是估计值,可能并不总是准确的。


filtered列


该列表示按表条件过滤的表行的估计百分比。最大值为100,这表示未过滤行。值从100减小表示过滤量增加。

12.png

rows显示了检查的估计行数,rows× filtered显示了与下表连接的行数。例如,如果 rows为1000且 filtered为50.00(50%),则与下表连接的行数为1000×50%= 500。


Extra列


该字段包含有关MySQL如何解析查询的其他信息,这列还是挺重要的,但是里面包含的值太多,就不一一介绍了,只列举几个常见的。


  1. Impossible WHERE


表示WHERE后面的条件一直都是false,

执行sql如下

explain select code  from test1 where 'a' = 'b';
  1. 结果:
    13.png


  1. Using filesort


表示按文件排序,一般是在指定的排序和索引排序不一致的情况才会出现。


执行sql如下

explain select code  from test1 order by name desc;


结果:

14.png

这里建立的是code和name的联合索引,顺序是code在前,name在后,这里直接按name降序,跟之前联合索引的顺序不一样。


3.Using index

表示是否用了覆盖索引,说白了它表示是否所有获取的列都走了索引。


15.png

上面那个例子中其实就用到了:Using index,因为只返回一列code,它字段走了索引。


4.Using temporary

表示是否使用了临时表,一般多见于order by 和 group by语句。

执行sql如下

explain select name  from test1 group by name;


结果:

16.png


5.Using where

表示使用了where条件过滤。


6.Using join buffer

  表示是否使用连接缓冲。来自较早联接的表被部分读取到联接缓冲区中,然后从缓冲区中使用它们的行来与当前表执行联接。



索引优化的过程


  1.先用慢查询日志定位具体需要优化的sql


  2.使用explain执行计划查看索引使用情况


  3.重点关注:

      key(查看有没有使用索引)


      key_len(查看索引使用是否充分)


      type(查看索引类型)

 

      Extra(查看附加信息:排序、临时表、where条件为false等)


  一般情况下根据这4列就能找到索引问题。


  4.根据上1步找出的索引问题优化sql


  5.再回到第2步

相关文章
|
6天前
|
SQL 关系型数据库 MySQL
explain是什么?explain优缺点及如何使用explain优化SQL
explain是什么?explain优缺点及如何使用explain优化SQL
25 1
|
2月前
|
存储 SQL 关系型数据库
explain详解和索引最佳实践
explain详解和索引最佳实践
|
2月前
|
存储 关系型数据库 MySQL
MySQL技能完整学习列表6、查询优化——1、EXPLAIN命令的使用——2、索引优化
MySQL技能完整学习列表6、查询优化——1、EXPLAIN命令的使用——2、索引优化
22 0
|
4月前
|
SQL 架构师 关系型数据库
SQL优化终于干掉了“distinct”
SQL优化终于干掉了“distinct”
53 0
|
8月前
|
SQL 存储 缓存
Mysql优化之explain你真的会吗?
Mysql优化之explain你真的会吗?
43 0
|
存储 关系型数据库 MySQL
|
存储 SQL 关系型数据库
Mysql优化之索引(二)
Mysql优化之索引(二)
Mysql优化之索引(二)
|
SQL 存储 关系型数据库
你不得不知的MYSQL优化——索引下推
你不得不知的MYSQL优化——索引下推
140 0
你不得不知的MYSQL优化——索引下推
|
NoSQL MongoDB 开发者
索引的使用 执行计划 | 学习笔记
快速学习 索引的使用 执行计划
56 0
索引的使用 执行计划 | 学习笔记
|
SQL 关系型数据库 MySQL
MySQL索引详解(优缺点,何时需要/不需要创建索引,索引及sql语句的优化)
目录 MySQL索引详解(优缺点,何时需要/不需要创建索引,索引及sql语句的优化) 一、什么是索引? 二、索引的作用? 三、优点: 四、缺点 五、什么时候需要创建索引 六、什么时候不需要创建索引 七、索引的分类: 八、索引和sql语句的优化 1、前导模糊查询不能使用索引, 2、Union、in、or可以命中索引,建议使用in 3、负条件查询不能使用索引,可以优化为in查询, 4、联合索引最左前缀原则,又叫最左侧查询, 5、建立联合查询时,区分度最高的字段在最左边 6、如果建立了(a,b)联合索引,就不必再单独建立a索引。 7、存在非等号和等号混合判断条件时,在建索引时,要把等号条件的列前置
261 0
MySQL索引详解(优缺点,何时需要/不需要创建索引,索引及sql语句的优化)

相关课程

更多