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步

相关文章
|
12月前
|
JSON API 数据安全/隐私保护
使用curl命令在服务器上执行HTTP请求
总的来说,curl是一个非常强大的工具,它可以让你在命令行中发送各种类型的HTTP请求。通过学习和实践,你可以掌握这个工具,使你的工作更加高效。
1103 30
|
SQL 数据库
Spring5入门到实战------13、使用JdbcTemplate操作数据库(批量增删改)。具体代码+讲解 【下篇】
这篇文章是Spring5框架的实战教程,深入讲解了如何使用JdbcTemplate进行数据库的批量操作,包括批量添加、批量修改和批量删除的具体代码实现和测试过程,并通过完整的项目案例展示了如何在实际开发中应用这些技术。
Spring5入门到实战------13、使用JdbcTemplate操作数据库(批量增删改)。具体代码+讲解 【下篇】
|
自然语言处理 Serverless 测试技术
DeepSeek 模型快速体验,魔搭+函数计算一键部署模型上云
DeepSeek模型近期备受关注,其开源版本DeepSeek-V3和DeepSeek-R1在多个基准测试中表现出色,性能比肩OpenAI顶尖模型。为降低本地部署门槛,Modelscope社区推出DeepSeek-R1-Distill-Qwen模型的一键部署服务,支持函数计算FC平台的闲置GPU实例,大幅降低成本。用户可选择不同参数量的小模型进行快速部署和推理,体验DeepSeek的强大性能。
DeepSeek 模型快速体验,魔搭+函数计算一键部署模型上云
|
监控 Java API
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
551 3
|
机器学习/深度学习 存储 缓存
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
文章主要介绍了排序算法的分类、时间复杂度的概念和计算方法,以及常见的时间复杂度级别,并简单提及了空间复杂度。
814 1
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
|
NoSQL Linux Redis
linux安装单机版redis详细步骤,及python连接redis案例
这篇文章提供了在Linux系统中安装单机版Redis的详细步骤,并展示了如何配置Redis为systemctl启动,以及使用Python连接Redis进行数据操作的案例。
527 3
|
关系型数据库 数据库 PostgreSQL
PostgreSQL索引维护看完这篇就够了
PostgreSQL索引维护看完这篇就够了
1442 0
|
JSON 中间件 数据格式
五、Flask的请求和响应方法与常用技巧
五、Flask的请求和响应方法与常用技巧
573 0
|
JSON 前端开发 API
[flask]统一API响应格式
[flask]统一API响应格式
301 1
|
存储 算法 Java
分布式自增ID算法---雪花算法(SnowFlake)Java实现
分布式自增ID算法---雪花算法(SnowFlake)Java实现
1707 0

热门文章

最新文章