您现在的位置是:首页 > 编程 > 

第 49 期:根据 EXPLAI EXTRA 栏提示进行优化(一)

2025-07-22 10:22:29
第 49 期:根据 EXPLAI EXTRA 栏提示进行优化(一) 作者:杨涛涛,爱可生技术专家。爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。往期推荐第 46 期:EXPLAI:解说一条简单语句的执行计划 第 47 期:EXPLAI TYPE 列的 JOI 常见场景详解(上) 第 48 期:EXPLAI TYPE 列的 JOI 常见场景详解(下)经过前面

第 49 期:根据 EXPLAI EXTRA 栏提示进行优化(一)

作者:杨涛涛,爱可生技术专家。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


往期推荐

第 46 期:EXPLAI:解说一条简单语句的执行计划

第 47 期:EXPLAI TYPE 列的 JOI 常见场景详解(上)

第 48 期:EXPLAI TYPE 列的 JOI 常见场景详解(下)

经过前面篇幅的持续阅读,相信大家对 MySQL 的执行计划已经有了一个较为深入的理解。本篇将对传统执行计划输出结果里的 Extra 栏进行逐步解析,从而使得大家更进一步的了解 MySQL 的 SQL 优化过程。

对于 MySQL 来讲,默认的 EXPLAI 结果里有一个 Extra 栏,其信息是 MySQL 对指定 SQL 执行计划的一些更加易读的数据,类似于提示信息。比如,是否用到临时表?是否用到排序?是否索引下推到引擎层?是否需要回表?等等。

接下来我们逐一讲解常见的 Extra 信息。

1Using index

这条提示信息是最为常见的,表示这条 SQL 可以不用回表,只需要扫描现存索引结构即可拿到所需记录;需要对索引中的记录按照索引顺序进行扫描;一般来讲,默认的索引顺序都是升序的,也就是从小到大的顺序进行扫描。

举个例子:

代码语言:javascript代码运行次数:0运行复制
localhost:ytt>desc select  r1 from t1 where 1 order by r1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
   partiti: ULL
         type: index
possible_keys: ULL
          key: idx_r1
      key_len: 5
          ref: ULL
         rows: 101745
     filtered: 100.00
        Extra: Using index
1 row in set, 1 warning (0.00 sec)

这条 SQL 只从表 t1 里拿字段 r1,并且字段 r1 上也有索引,Extra 栏里此时就会显示 Using index 。

所以单从数据库角度来讲,很多公司里定制的开发规范都强调在写 SQL 时,只需拿必要字段而不推荐写 SELECT * 也是很有道理的。

2Backward index scan

这条提示信息代表此条 SQL 可以走索引,不过没有按照索引顺序扫描,而是反向扫描;一般来讲,这个提示信息发生在需要倒序扫描索引记录的业务。

举个例子:

代码语言:javascript代码运行次数:0运行复制
localhost:ytt>desc select  r1 from t1 where 1 order by r1 desc\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
   partiti: ULL
         type: index
possible_keys: ULL
          key: idx_r1
      key_len: 5
          ref: ULL
         rows: 101745
     filtered: 100.00
        Extra: Backward index scan; Using index
1 row in set, 1 warning (0.00 sec)

和第一条 SQL 很类似, 不同的是这条 SQL 获取字段 r1 的顺序刚好相反。如果单从执行效率角度来讲,升序和倒序的方式其实没有什么大的差别,仅仅是索引数据存储的方式不同。不过我个人还是建议严格按照顺序来设计对应的索引,比如针对这条 SQL 来讲,如果可以的话,需要单独创建一个倒序索引:

代码语言:javascript代码运行次数:0运行复制
localhost:ytt>alter table t1 add key idx_r1_desc(r1 desc);
Query OK, 0 rows affected (1.68 sec)
Records: 0  Duplicates: 0  Warnings: 0
Select tables optimized away

这条提示信息表示此条 SQL 在 MySQL 里是以最优化的方式来执行。可以这样理解:SQL 不需要实际执行即可拿到结果,也就是说 SQL 在被优化器交给执行器之前就可以拿到结果,不需要实际执行;更简单来讲,就是不需要实际查询实体表,而仅仅依赖 SQL 过滤条件中的常量等就可以提前拿到结果。比如以下两种场景:

  1. 返回结果最多只能有一行。
  2. 这一行必须从一个确定的结果集中获取。

举个例子:

代码语言:javascript代码运行次数:0运行复制
localhost:ytt>desc select min(r2),max(r) from t1 \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
   partiti: ULL
         type: ALL
possible_keys: ULL
          key: ULL
      key_len: ULL
          ref: ULL
         rows: 101745
     filtered: 100.00
        Extra: ULL
1 row in set, 1 warning (0.00 sec)

对于以上这条 SQL ,检索表 t1 字段 r2 的最小值以及字段 r 的最大值,需要全表扫,加个索引后,执行计划就变为如下:

代码语言:javascript代码运行次数:0运行复制
localhost:ytt>alter table t1 add key idx_r2(r2), add key idx_r(r);
Query OK, 0 rows affected (2.86 sec)
Records: 0  Duplicates: 0  Warnings: 0

localhost:ytt>desc select min(r2),max(r) from t1 \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: ULL
   partiti: ULL
         type: ULL
possible_keys: ULL
          key: ULL
      key_len: ULL
          ref: ULL
         rows: ULL
     filtered: ULL
        Extra: Select tables optimized away
1 row in set, 1 warning (0.00 sec)

此时,执行计划变为:Select tables optimized away,也就是以最优的方式来得到结果,不需要访问实体表。

再来举个例子:

代码语言:javascript代码运行次数:0运行复制
localhost:ytt>desc select min(r2) from t1 where r2 = 1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: ULL
   partiti: ULL
         type: ULL
possible_keys: ULL
          key: ULL
      key_len: ULL
          ref: ULL
         rows: ULL
     filtered: ULL
        Extra: Select tables optimized away
1 row in set, 1 warning (0.00 sec)

对于这条 SQL 来讲, 字段 r2=1 的结果集是固定的,并且 min(r2) 的结果刚好是 r2=1, 从优化器角度来看,不需要访问实体表即可拿出结果。

4Zero limit

这个表示 SQL 语句使用了 LIMIT 0 子句。如果有需要检查语句合法性的需求,可以给语句后面加 LIMIT 0,比如:

代码语言:javascript代码运行次数:0运行复制
localhost:ytt>desc select  r1 from t1 where 1 order by r1 limit 0\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: ULL
   partiti: ULL
         type: ULL
possible_keys: ULL
          key: ULL
      key_len: ULL
          ref: ULL
         rows: ULL
     filtered: ULL
        Extra: Zero limit
1 row in set, 1 warning (0.00 sec)

当然不加 LIMIT 0 也是可以,MySQL 在语法分析阶段会自动给出 SQL 语句的合法性;加 LIMIT 0 主要是从业务的角度来体验 SQL 语句的合法性。

本篇暂且到此,欢迎继续关注后续内容。

本文参与 腾讯云自媒体同步曝光计划,分享自。原始发表:2025-01-14,如有侵权请联系 cloudcommunity@tencent 删除null索引优化sqlkey

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1176130.html

相关标签:无
上传时间: 2025-07-21 17:24:47

上一篇:python在Scikit

下一篇:对话Leonis Capital

留言与评论(共有 10 条评论)
本站网友 六网
16分钟前 发表
本篇将对传统执行计划输出结果里的 Extra 栏进行逐步解析
本站网友 toyota汽车
20分钟前 发表
1 select_type
本站网友 羌胡
10分钟前 发表
0 rows affected (1.68 sec) Records
本站网友 香港政府网站
30分钟前 发表
并且字段 r1 上也有索引
本站网友 浙江今日证券
7分钟前 发表
第 49 期:根据 EXPLAI EXTRA 栏提示进行优化(一) 作者:杨涛涛
本站网友 贝利珠
7分钟前 发表
ULL Extra
本站网友 中药新药
18分钟前 发表
1 warning (0.00 sec) 和第一条 SQL 很类似
本站网友 北京旺铺招租
9分钟前 发表
101745 filtered
本站网友 家装油漆十大品牌
28分钟前 发表
SIMPLE table