274_DBA_执行计划_extra

举报
alexsully 发表于 2022/01/25 18:43:52 2022/01/25
【摘要】 extra 信息概述

Extra

提示执行计划的一些额外信息

1 No tables used  

当查询中没有from子句,会提示该字眼

explain select @@server_uuid

2 Impossible Where

查询语句中where子句用于为false时 提示该信息

explain select * from s1 where 1 < 0

3 No matching min/max row

当查询 有使用 MIN / MAX 聚集函数,单没有记录符合 where子句中的搜索条件时, 将会提示该信息

explain select min(key1) from s1 where key1="alex"

4 Using index

使用 覆盖索引执行查询时,仅通过扫描索引数即可 不需要回表 extra会打印 using index

explain select key1 from s1 where key1 = "alex";

5 Using index condition

有些搜索条件虽然出现了索引列 但不能充当边界条件来形成扫描区间, 就不能用来减少扫描的记录,但MySQL做了优化 index condition pushdown 来减少扫描聚簇索引

explain select key1 from s1 where key1 > "a" and key1 like "%a";

6 Using index condition

有些搜索条件虽然出现了索引列 但不能充当边界条件来形成扫描区间, 就不能用来减少扫描的记录,但MySQL做了优化 index condition pushdown 来减少扫描聚簇索引

explain select key1 from s1 where key1 > "a" and key1 like "%a";

 Index condition  pushdown 索引下推

虽然 where key1 like “%a” 不能充当边界条件来减少扫描二级索引记录,但是where条件中仅涉及 key1 ; MySQL做了如下优化

  • 1 server层调用 innodb接口定位到满足 key1 > “a” 的第一条二级索引记录
  • 2 innodb 根据二级索引找到第一条记录后,并不急于回表, 而是判断 key1 like "%a" 是否成立,如果不成立跳过,成立回表取所有数据 返回server
  • 3 server层判断其它条件 是否满足

综上: 如果每次扫描到第一条条件就回表 加载数据页,这样耗费性能, 做了不着急回表 在索引B数上判断其它条件,如果满足就回表

索引条件下推特性只是为了在扫描某个扫描区间的二级索引记录时,尽可能减少回表操作次数,减少IO操作,如果对于聚簇索引,不需要回表,起不到减少IO操作

 

7 Using where

当某个搜索条件需要在server层进行判断,extra列就会提示 using where

explain select * from s1 where  key1 = "a" and key3 = "cc";

8 Using join bufferBlock Nested Loop

当被驱动表不能有效利用索引, mysql会利用 连接缓冲区(join buffer) 内存来加速查询, 也是基于嵌套查询

# using join buffer 对于 被驱动表S2 没用到索引, 使用where 是因为对应s2 where s2.commen_field= 一个常数 需要在server层进行判断

explain select * from s1 join s2 on s1.commen_field = s2.commen_field

9 Using intersect()  using union() using sort union() 

如果出现了 using intersect() 意味着优化器对索引进行了合并,减少检索范围

explain select * from s2 where  key1 = "a" or key3 = "a";

10 Zero limit

limit 子句参数为0, 表示压根不打算从表中读出任何记录,会提示 zero limit

explain select * from s2 where  key1 = "a" or key3 = "a" limit 0;

11 Using filesort  Using temporary

对结果集需要进行排序,且无法使用到索引,就需要在内存中 或者 磁盘上利用临时文件对结果集进行排序, 内存/磁盘上排序称为filesort , 如果过程中使用到了临时表 就是using temporary

explain select * from s2 order by s2.commen_field

有时候mysql会利用临时表完成排序,去重,分组等功能, distinct group by, union 等,且无法有效利用索引,就用内部临时表 会出现using temporary

explain select count(*) commen_field from s2  GROUP BY s2.commen_field

注意

有时候 using filesort using temporary 同时出现, 是因为mysql 默认给 group by 后面添加了 order by 子句; 实际生产中根据实际情况进行设计

explain select count(*) commen_field from s2  GROUP BY s2.commen_field  ORDER BY s2.commen_field

IN 转为 半连接 对应的 extra信息

12 Start temporary , end temporary

Start temporary , end temporary

优化器会尝试将in 转成半连接, 当策略为 duplicate_Weedout时(通过创建临时表方式为外层查询中的记录进行去重操作) 驱动表执行计划对应extrastart temporary, 被驱动表为 end temporary

explain select * from s1 where key2 in (SELECT key2 from s2 where s2.commen_field = "alex")

# 其实优化器将SQL 优化成 select * from s1 semi join s2 on s1.key2 = s2.key2 where s2.commen_field = "alex"   将s2 当成了驱动表

 

13 looseScan

in 子查询 转成 semi join ,如果采用looseScan (虽然是扫描索引,但只取键值相同的第一条记录去匹配) 则驱动表执行计划 extra 显示looseScan

# 转成semi join  select * from s1 semi join s2 on  s1.key3= s2.key1 where s2.key1 like “a%”

# 转成semi join s2 作为驱动表; 基于索引 key1检索中结果集符合 s2.key1 like “a%” 可能有 3865条,例 aalex aalex abob abob, 再做代入内层循环时候,只会取第一个 s2.key1 =aalex 作为条件代入 内层循环去判断 是否能在 s1 找到对应的记录,如果能找到就返回结果集,不能找到则进行下一次判断

备注: 只会取键值相同的第一条记录去进行判断

explain select * from s1 where s1.key3 in (SELECT key1 from s2 where s2.key1 like  "a%"  )

14 FirstMatch(tableName)

首次匹配时最原始的semi join 执行方式, 先去外层查询一条记录, 然后到子查询中寻找服务匹配条件的记录

# s2 是子查询 意味着会被执行多次 且要判断是否符合外层传入的列值

explain select * from s1 where s1.commen_field in (SELECT key1 from s2 where s2.key1 = s1.key1)

               

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。