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步

相关文章
|
2月前
|
SQL 存储 关系型数据库
如何巧用索引优化SQL语句性能?
本文从索引角度探讨了如何优化MySQL中的SQL语句性能。首先介绍了如何通过查看执行时间和执行计划定位慢SQL,并详细解析了EXPLAIN命令的各个字段含义。接着讲解了索引优化的关键点,包括聚簇索引、索引覆盖、联合索引及最左前缀原则等。最后,通过具体示例展示了索引如何提升查询速度,并提供了三层B+树的存储容量计算方法。通过这些技巧,可以帮助开发者有效提升数据库查询效率。
191 2
|
2月前
|
SQL Oracle 关系型数据库
SQL优化-使用联合索引和函数索引
在一次例行巡检中,发现一条使用 `to_char` 函数将日期转换为字符串的 SQL 语句 CPU 利用率很高。为了优化该语句,首先分析了 where 条件中各列的选择性,并创建了不同类型的索引,包括普通索引、函数索引和虚拟列索引。通过对比不同索引的执行计划,最终确定了使用复合索引(包含函数表达式)能够显著降低查询成本,提高执行效率。
|
2月前
|
SQL 机器学习/深度学习 关系型数据库
最完整的Explain总结,SQL优化不再困难!
最完整的Explain总结,SQL优化不再困难!
|
7月前
|
存储 SQL 关系型数据库
explain详解和索引最佳实践
explain详解和索引最佳实践
|
SQL 存储 缓存
Mysql优化之explain你真的会吗?
Mysql优化之explain你真的会吗?
81 0
|
存储 关系型数据库 MySQL
索引及查询优化
索引及查询优化
68 0
|
存储 SQL 关系型数据库
Mysql优化之索引(二)
Mysql优化之索引(二)
Mysql优化之索引(二)
|
存储 关系型数据库 MySQL
|
SQL 存储 关系型数据库
你不得不知的MYSQL优化——索引下推
你不得不知的MYSQL优化——索引下推
245 0
你不得不知的MYSQL优化——索引下推
|
NoSQL MongoDB 开发者
索引的使用 执行计划 | 学习笔记
快速学习 索引的使用 执行计划
索引的使用 执行计划 | 学习笔记

相关实验场景

更多