解读执行计划l对于我们日常工作中慢sql的分析和调优有很大帮助,同时在解读的过程中也能知道如何规避慢sql
执行顺序 值越大的优先执行 如果相同则根据从上到下的顺序来确定 如果为null则最后执行
先执行id为2查询 将查询结果保存为临时表,再执行id为1的 从上到下,先将lb为驱动表关联查询lh得出结果 subquery2临时表 然后作为临时表去非驱动表ls查询数据
4、DEPENDENT SUBQUERY子查询依赖外部查询,慎用5、DERIVED:在from列表中包含的子查询被标记为derived(衍生),mysql或递归执行这些子查询,把结果放在临时表里
慎用子查询依赖外部查询,会先根据外部查询得出一个临时表 再根据临时表 去触发子查询因为p表没有查询条件 每条数据都会触发一次o表查询 现在数据 566条 相当于触发了566 t2 select 数据量大就更夸张(就算t2走了索引页会导致性能问题) 建议改成select join group by 可以理解为p表查询结果为临时表。在for循环遍历每一条数据 查询o表
子查询位于form处 先通过create_timestamp查询结果到临时表 再根据临时表id查询
table列表示EXPLAIN的单独行的唯一标识符。这个值可能是表名、表的别名或者一个未查询产生临时表的标识符,如派生表、子查询或集合。
当FROM子句中有子查询时,如果优化器采用的物化方式,table 列是derivenN格式,表示当前查询依赖id=N的查询,于是先执行id=N的查询。
这一列表示关联类型或访问类型,即MySQL决定如何查找表中的行,查找数据行记录的大概范围。依次从最优到最差分别为:
表示通过扫描索引 扫描一行就找到了数据 const用于比较primary key 或者 unique索引。因为只需匹配一行数据,所有很快。如果将主键置于where列表中,mysql就能将该查询转换为一个const
index_merge其实就是分别通过对两个独立的index进行过滤之后,将过滤之后的结果聚合在一起,然后在返回结果集
我们的 where 中可能有多个条件(或者join)涉及到多个字段,它们之间进行 AND 或者 OR,那么此时就有可能会使用到 index merge 技术。index merge 技术如果简单的说,其实就是:对多个索引分别进行条件扫描,然后将它们各自的结果进行合并(intersect/union)。
MySQL5.0之前,一个表一次只能使用一个索引,无法同时使用多个索引分别进行条件扫描。但是从5.1开始,引入了 index merge 优化技术,对同一个表可以使用多个索引分别进行条件扫描。
index merge使得我们可以使用到多个索引同时进行扫描,然后将结果进行合并。听起来好像是很好的功能,但是如果出现了 index intersect merge,那么一般同时也意味着我们的索引建立得不太合理,因为 index intersect merge 是可以通过建立 复合索引进行更一步优化的。
版权声明:本文为CSDN博主「lazzZa」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
指出MySQL可能使用哪个索引在表中找到行,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用
实际使用的索引,如果为NULL,则没有使用索引,如果出现possible_keys有值但是 key为null 可能是在数据少量情况下 mysql优化器认为全表扫描比走索引快,所以放弃使用索引
表示索引中使用的字节数,查询中使用的索引的长度(最大可能长度),并非实际使用长度,理论上长度越短越好。key_len是根据表定义计算而得的,不是通过表内检索出的
注意:该索引列可以存储NULL值,则key_len比不可以存储NULL值时多1个字节。
索引最大长度是768字节,当字符串过长时,MySQL 会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索引。
ref列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),字段名(例:user.id)
如果查询优化器使用全表扫描查询,rows列代表预计的需要扫码的行数;如果查询优化器使用索引执行查询,rows列代表预计扫描的索引记录行数。
Extra列提供了一些额外信息。这一列在 MySQL中提供的信息有几十个,这里仅列举一些常见的重要值如下:
查询的列被索引覆盖,并且WHERE筛选条件是索引列之一 id为主键 name为普通索引
查询的列未被索引覆盖,并且WHERE筛选条件是索引的前导列,意味着用到了索引,但是部分字段未被索引覆盖,必须通过回表来查询,不是纯粹地用到了索引,也不是完全没用到索引。
查询的列不完全被索引覆盖 where条件为二级索引 需要根据二级索引存储的聚簇索引id 获得数据才能拿到introduction(回表)
表示mysql需要临时表转存数据 常见于 group by、DISTINCT、ORDER BY使用非索引字段 一般出现这种情况就需要考虑进行优化了,首先是想到用索引来优化。
如果一个排序操作不能通过索引来完成,那这次排序操作就叫做filesort,这跟file没有任何关系。filesort应该叫做sort,而它的实现,就是大家熟悉的快排(一般由于 排序列没有建索引导致)
id为聚簇索引 name为非聚簇索引 通过聚簇索引name查找可以找到id 无须回表查询效率高
id为聚簇索引 name为非聚簇索引,sex为非索引,sex需要根据聚簇索引获取到对应的数据行(回表操作) 如果将name和sex升级为联合索引则无须回表
这里我们将联合索引最左name排在后面 也能正常使用索引时因为mysql优化后会帮我们排在前面,在写的过程中 还是要根据联合索引顺序编写,避免二次优化
如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。
其实很好理解比如你通过hashMap存储根据name快速找到对应对象,如果你要根据key做处理匹配 就只能遍历keys 做完处理再比较
但是如果你正式查询条件使用函数,你只是在get之前 通过函数转了一下查询值 不会影响索引
1覆盖索引:简单理解,只访问建了索引的列。减少使用SELECT *语句查询列。 避免回表
可以看到s_no没有走 索引 因为数据量比较小,sql优化引擎认为全表扫描比索引快,因为会回表 需要查询2次
因为是or查询,所以格努work_age找索引 没有满足最左前缀匹配将全表扫描
id2 后面extra是因为 唯一索引如果查询不存在的值将不会走索引 参考:
注意所以再日常使用中不要使用 先查询判断是否存在 再插入 直接插入 让mysql抛出异常 并捕获异常比如用户注册,但是建立了唯一索引查询的时候就要特别注意 查询的地方
因为字段更新台频繁,会导致B+树的频繁的变更,重建索引。所以这个过程是十分消耗数据库性能的。
比如类似性别这类的字段,区分度不大,建立索引的意义不大。因为不能有效过滤数据,性能和全表扫描相当。另外注意一点,返回数据的比例在30%之外的,优化器不会选择使用索引。
业务中如果有唯一特性的字段,即使是多个字段的组合,也尽量都建成唯一索引。尽管唯一索引会影响插入效率,但是对于查询的速度提升是非常明显的。此外,还能够提供校验机制,如果没有唯一索引,高并发场景下,可能还会产生脏数据。
下一篇:广东工业大学申请基于物联网的物流配送路径智能管理方法及系统专利实现复杂环境下路径的自适应、高效优化与可靠执行
