MySQL执行计划解读

前言

​ MySQL查询进行SQL查询,一般要求尽量使用到索引,否则会导致全表扫描。

问题1:全表扫描会产生什么问题?全表扫描实际上是直接扫描表的主键索引,依次读并发送。详细介绍,查看以下博客。MySQL-全表扫描 以及MySQL-全表扫描成本计算

​ 另外,简单查询是不会加锁的。例如select * from table;

问题2:怎么确定有没有使用到索引?explain关键字

Explain

​ 使用Explain关键字查询SQL执行情况,结果会有以下几个字段。分别是:id、select_type、table、type、possible_keys、key、key_len、rows、Extra。

select_type 查询类型

select_type查询类型说明
SIMPLE简单的 select 查询,不使用 union 及子查询
PRIMARY最外层的 select 查询
SUBQUERY在select或者where中包含了子查询,子查询中的第一个 select 查询,不依赖于外部查询的结果集
DEPENDENT SUBQUERY子查询中的第一个 select 查询,依赖于外部 查询的结果集
DERIVED用于 from 子句里有子查询的情况。 MySQL 会递归执行这些子查询, 把结果放在临时表里。
UNIONUNION 中的第二个或随后的 select 查询,不 依赖于外部查询的结果集
DEPENDENT UNIONUNION 中的第二个或随后的 select 查询,依 赖于外部查询的结果集
UNCACHEABLE UNIONUNION 中的第二个或随后的 select 查询,属 于不可缓存的子查询

简单来说就是:

SIMPLE:简单的 select 查询,不使用 union 及子查询
PRIMARY:也就是最后执行的语句
SUBQUERY:在select或者where中包含了子查询
DERIVED:临时表会增加MYSQL负担,但是有时候不得不用,类比:Java中两个变量交换数值
UNION:两个表的查询结果合并

type 对表的访问方式

  • ALL 全表扫描

  • index 索引全扫描

  • range 索引范围扫描。索引范围扫描的结果可能会返回多条记录,例如:一般条件查询中出现了>、<、in、between等查询

  • ref 使用非唯一索引扫描或唯一索引前缀扫描,返回单条记录,常出现在关联查询中

  • eq_ref 类似ref,区别在于使用的是唯一索引,使用主键的关联查询

  • const/system 单条记录,系统会把匹配行中的其他列作为常数处理,如主键或唯一索引查询

  • null MySQL不访问任何表或索引,直接返回结果 虽然上至下,效率越来越高,但是根据cost模型,假设有两个索引idx1(a, b, c),idx2(a, c),SQL为"select * from t where a = 1 and b in (1, 2) order by c";如果走idx1,那么是type为range,如果走idx2,那么type是ref;当需要扫描的行数,使用idx2大约是idx1的5倍以上时,会用idx1,否则会用idx2

possible_keys:表示查询时,可能使用的索引;

possible_keys有值,而key显示为null
这种情况是因为表中数据不多,mysql认为索引对此查询帮助不大,选择了全表查询。

possible_keys无值
表示没有相关的索引,可以通过检查where子句看是否可以创造一个适当的索引来提高查询性能。

key:表示实际使用的索引

key_len:索引字段的长度

ref:列与索引的比较

rows:扫描出的行数(估算的行数)

Extra:执行情况的描述和说明。

​ 这个字段里面常见有:Using where、Using index、Using index condition、Using filesort、Using temporary。

  • Using where:表示优化器需要通过索引回表查询数据;

  • Using index:表示直接访问索引就足够获取到所需要的数据,不需要通过索引回表;

  • Using index condition(5.6新特性):会先条件过滤索引,过滤完索引后找到所有符合索引条件的数据行,随后用 WHERE 子句中的其他条件去过滤这些数据行;

  • Using filesort:**表示需要进行排序操作,且无法使用索引进行排序。**MySQL需要额外的一次传递,以找出如何按排序顺序检索行。通过根据联接类型浏览所有行并为所有匹配WHERE子句的行保存排序关键字和行的指针来完成排序。然后关键字被排序,并按排序顺序检索行。

  • Using temporary:**表示使用了临时表来存储中间结果。**性能特别差,需要重点优化

  • Using join buffer:表示使用了连接缓存区来存储连接结果。

  • Impossible WHERE:表示查询条件不可能为真,通常由于使用了错误的函数或者运算符导致的。

示例:

SQL: select * from tbale where no = ‘1’ and no_name is null;

此数据为新增数据、索引字段为no。

示例:Using index condition; Using where

代表会先条件过滤索引,找到符合索引条件的数据后,再进行其他条件过滤。另外这次的结果是通过索引回表查询的结果。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值