懂的越多,不懂的越多
说到面试,只要提到数据库,必然会提到数据库优化,相应的关于索引这一大块内容也随之而来,那么如何观测我们索引方面的优化是不是有效,就涉及到今天要提到Explain。
参数 | 含义 |
---|---|
id | sql的子句或者表的执行顺序,标号大的先执行,标号相同的按顺序执行 |
select_type | 使用的查询类型,用来区分普通查询、联合查询、子查询,有 SIMPLE,PRIMARY,UNION,DEPENDENT UNION,SUBQUERY… |
table | 对应的表名,可以是别名,有时不是真实的表名,而是一个代指 |
partitions | 通常为空或者null,如果查询分区表的话,那就显示访问的那个分区 |
type | 查询的关联类型或访问类型,上一篇有详细的说过这个属性,一般来讲,应当避免sql出现index或者all这两个级别出现,因为这两个级别都是属于要遍历所有数据 |
possible_keys | 查询时可能使用的索引,这个属性对于优化查询效率来说,极其重要,一个好的索引策略会大大提高效率,但是差的索引有时效果并不好,甚至还因为维护起来消耗过大,还不如不建立索引。 |
key | 实际使用的索引,要知道查询优化,不是建立索引就完事了,还要知道索引是不是使用,有可能你建立的索引被优化器嫌弃,而没有使用哦!!! |
key_len | 索引使用的字节数,比如int是4个字节,通过字节数和表的定义,就可以知道使用的是那个索引。 |
ref | 索引使用的是哪一列,常见的值有const(常量),NULL,字段名(表.列名) |
rows | 需要查询的行数,需要注意的是,这个值是一个估算值,通常这个值越少代表索引的效率越高。 |
filtered | 这是一个百分比的数值,返回结果的行占到需要查询行数的比例,通常是100,这个涉及到一个mysql的一个问题,mysql因为只统计索引列的唯一数和表的总记录数,因此join如果不加索引,经常会出现,数据量大的表和数据量小的表的查询顺序问题。总结下就是这个字段基本没啥用,能看见的基本都是100. |
extra | 你乐意叫他其他或者备注都行,主要内容就是执行时的一些细节,比如截图中的Using where(表示服务器将存储引擎查询到的数据返回服务层以后再应用WHERE条件过滤),Using index(表示索引数中就有查询的数据,不需要去劳烦存储引擎了) |
总结
Mysql优化关注点:
1.执行顺序对应的表,关注是否是优先去查询数据量小的表,从而减少查询数据的行数
2.判断是否使用了高效的类型,避免出现all和index
3.关注下是不是执行了规划好的索引,或者说如果没有走预先建立的索引,反思下是不是索引建立的有问题
4.关注下查询的行数,这个数据很直观,越少越好。
5.关注下extra,查看下是否在有出现Using filesort(排序),Using temporary(临时表),我们知道索引会自带排序功能,因此排序的额外消耗很不应该,临时表效率也比较低,尽量优化掉。
explain执行计划的成本估算,依赖于存储引擎的统计信息,而InnoDB比较扯得一方面,就是其统计信息并不一定准确并且还只有表的总列和索引得唯一列值这两个值,所以要记住的是成本估算并不等价于实际成本,因此,生成的执行计划也不等价于最优解。
上篇文章有提到一个问题,explain的执行计划和实际的运行计划有时并不一致,通过上边关于explain的描述我们可以想象的到有可能的几个点
1.因为统计信息不准确引起的,explain的执行计划是根据统计信息生成的,如果统计信息不准确就会导致执行计划有问题
2.explain有一个问题,不会计算变量的转换,我们在写sql时,会发现,服务会给sql进行一些变量的自动匹配,这时就会消耗额外的资源,从而导致执行计划不一致