很早之前就知道explain,但是缺少总结,所以一提起来虽然貌似熟悉,但是印象茫然。
当时觉得这个工具,涉及到的东西很多,一下子不知道怎么总结。
根据实践论的观点,人对外界的认识是由浅入深,从片面到全面的。所以没必要一开始就对自己要求那么高,只需要进步、积累一点即可。
记事者必提其要,篡言者必钩其玄。
rows:返回估算的结果集数目,注意这并不是一个准确值。
type 访问类型(由差到好):
- ALL 扫描全表数据
- index 遍历索引
- range 索引范围查找
- ref 使用非唯一索引查找数据
- const 使用主键或者唯一二级索引,且匹配的结果只有一条记录。
extra 更多信息: - Using index:使用了覆盖索引。查询在索引树中就可以找到所有数据,不用回主键索引树查找,往往说明性能不错
- Using where:使用了用where子句来过滤结果集
- Using filesort:使用文件排序,使用非索引列进行排序时出现。MySQL需要进行额外的排序来获取数据,无法通过索引顺序达到排序效果(黑名单,绝对禁止)
- Using temporary:使用临时表。MySQL需要创建临时表来存放数据,一般出现于排序,分组和多表join的情况(黑名单,绝对禁止)
关于覆盖索引(covering index)指一个查询语句的执行只用从索引中就能够取得,不必从数据表中读取。也可以称之为实现了索引覆盖
2019-04-10补充:
什么是index(遍历索引)?
SELECT key_part1, key_part2, key_part3 FROM single_table WHERE key_part2 = 'abc';
由于 key_part2并不是联合索引 idx_key_part最左索引列,所以我们无法使用 ref或者 range访问方法来执行这个语句。但是这个查询符合下边这两个条件:
它的查询列表只有3个列: key_part1, key_part2, key_part3,而索引 idx_key_part又包含这三个列。
搜索条件中只有 key_part2列。这个列也包含在索引 idx_key_part中。
也就是说我们可以直接通过遍历 idx_key_part索引的叶子节点的记录来比较 key_part2='abc'这个条件是否成立,把匹配成功的二级索引记录的 key_part1, key_part2, key_part3列的值直接加到结果集中就行了。由于二级索引记录比聚簇索记录小的多(聚簇索引记录要存储所有用户定义的列以及所谓的隐藏列,而二级索引记录只需要存放索引列和主键),而且这个过程也不用进行回表操作,所以直接遍历二级索引比直接遍历聚簇索引的成本要小很多,设计 MySQL的大叔就把这种采用遍历二级索引记录的执行方式称之为: index。extra当然是 Using index
索引杀手:关键字 OR, IN
在 where 子句中使用 or 来连接条件,引擎将放弃使用索引而进行全表扫描。
在 where 子句中使用 in和not in,引擎将放弃使用索引而进行全表扫描。
select * from t where num=10 or num=20
select * from t where num in (10,20)
替换为
select * from t where num=10
union all
select * from t where num=20
或者
select * from t where num between 10 and 20
需要注意,如果是select id from t where num=10 or num=20,那么不需要再回到聚集索引中查询(回表),访问方式是range, MySQL版本是5.7.25
2019-05-14补充:
在访问类型type中,有一种叫index_merge
select id from t where a= or b =
使用多个所以做并集
网友评论