第 49 期:根据 EXPLAI EXTRA 栏提示进行优化(一)
第 49 期:根据 EXPLAI EXTRA 栏提示进行优化(一)
作者:杨涛涛,爱可生技术专家。
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
往期推荐
第 46 期:EXPLAI:解说一条简单语句的执行计划
第 47 期:EXPLAI TYPE 列的 JOI 常见场景详解(上)
第 48 期:EXPLAI TYPE 列的 JOI 常见场景详解(下)
经过前面篇幅的持续阅读,相信大家对 MySQL 的执行计划已经有了一个较为深入的理解。本篇将对传统执行计划输出结果里的 Extra 栏进行逐步解析,从而使得大家更进一步的了解 MySQL 的 SQL 优化过程。
对于 MySQL 来讲,默认的 EXPLAI 结果里有一个 Extra 栏,其信息是 MySQL 对指定 SQL 执行计划的一些更加易读的数据,类似于提示信息。比如,是否用到临时表?是否用到排序?是否索引下推到引擎层?是否需要回表?等等。
接下来我们逐一讲解常见的 Extra 信息。
这条提示信息是最为常见的,表示这条 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 *
也是很有道理的。
这条提示信息代表此条 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 来讲,如果可以的话,需要单独创建一个倒序索引:
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
这条提示信息表示此条 SQL 在 MySQL 里是以最优化的方式来执行。可以这样理解:SQL 不需要实际执行即可拿到结果,也就是说 SQL 在被优化器交给执行器之前就可以拿到结果,不需要实际执行;更简单来讲,就是不需要实际查询实体表,而仅仅依赖 SQL 过滤条件中的常量等就可以提前拿到结果。比如以下两种场景:
- 返回结果最多只能有一行。
- 这一行必须从一个确定的结果集中获取。
举个例子:
代码语言: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
的最大值,需要全表扫,加个索引后,执行计划就变为如下:
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
, 从优化器角度来看,不需要访问实体表即可拿出结果。
这个表示 SQL 语句使用了 LIMIT 0
子句。如果有需要检查语句合法性的需求,可以给语句后面加 LIMIT 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组装电脑配置单推荐报价格
上一篇: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 |