「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景

大家好,我是melo,一名大三后台练习生
专栏回顾
  • 索引的原理&&设计原则欢迎关注本专栏:MySQL高级篇
本篇速览在我们上一篇文章中,讲到了索引的原理&&设计原则 , 知道了索引如何使用 。emm?那具体什么场景需要用到索引,我们要怎么分析SQL语句,并对其进行优化呢,这篇将从以下几点带你攻破ta:
  • 详解explain分析SQL
  • 索引失效的几个场景
    • ......
  • SQL优化的几个场景
    • 大批量插入
    • order by
    • group by
    • limit分页
    • insert操作
    • 嵌套查询
    • or条件
注意,本文MySQL版本为5.6.43,部分结论在其他版本可能不适用?。。?
  • 本篇篇幅较长 , 全文近8500字,可以收藏下来慢慢啃,没事就掏出来翻阅翻阅 。
建议通过侧边栏目录检索对您有帮助的部分,其中有emoji表情前缀属于重点部分,觉得对您有帮助的话 , melo还会持续更进完善本篇文章和MySQL专栏 。
好 , 现在我们已经掌握了索引的基本原理和使用方法了,要来大干一场优化SQL了!等等,我们要优化什么SQL来着,裤子都脱了,结果没对象可以.....
「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景

文章插图
别着急,这篇既然挂着MySQL高级篇,自然MySQL还是很高级的,给我们提供了几种方法,来为我们找到SQL,并分析SQL 。本篇,我们先着重讲解如何分析,具体如何找到SQL,后续的实战篇,我们再来详细谈一谈 。
【一、explain】分析SQL
「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景

文章插图
explain中 , 包含了如下几个字段(不同版本可能会有所差异):
字段含义idselect查询的序列号 , 是一组数字,表示的是查询中执行select子句或者是操作表的顺序 。select_type表示 SELECT 的类型,常见的取值有 SIMPLE(简单表,即不使用表连接或者子查询)、PRIMARY(主查询 , 即外层的查询)、UNION(UNION 中的第二个或者后面的查询语句)、SUBQUERY(子查询中的第一个 SELECT)等table输出结果集的表partitions查询时匹配到的分区信息,对于非分区表值为NULL,当查询的是分区表时,partitions显示分区表命中的分区情况 。type表示表的连接类型 , 性能由好到差的连接类型为( system ---> const -----> eq_ref ------> ref -------> ref_or_null----> index_merge ---> index_subquery -----> range -----> index ------> all )possible_keys表示查询时,可能使用的索引key表示查询时,实际使用的索引key_len索引字段的长度 , 可用来区分长短索引rows扫描行的数量filtered表里符合条件的记录数所占的百分比extra执行情况的说明和描述
看完是不是很懵,感觉好多要记忆的,别着急,下边我们通过实际案例,来加深记忆
idid 字段是 select查询的序列号,是一组数字,表示的是查询中执行select子句或者是操作表的顺序 。id 情况有三种 :?
  1. 此处只是单表查询,id只有一个

「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景

文章插图
  1. id一样,则从上到下

「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景

文章插图
  1. id不同,则id值越大,优先级越高
此处是嵌套子查询 , 最内部的子查询,自然是最先执行的

「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景

文章插图
简而言之:
  • id值越大,优先级越高;
  • id值一样,则从上到下;
select_typeSELECT_TYPE含义SIMPLE简单的select查询 , 查询中不包含子查询或者UNIONPRIMARY查询中若包含任何复杂的子查询,最外层查询标记为该标识SUBQUERY在SELECT 或 WHERE 列表中包含了子查询DERIVED在FROM 列表中包含的子查询,被标记为 DERIVED(衍生) MYSQL会递归执行这些子查询,把结果放在临时表中UNION若第二个SELECT出现在UNION之后,则标记为UNION ; 若UNION包含在FROM子句的子查询中,外层SELECT将被标记为 : DERIVEDUNION RESULT从UNION表获取结果的SELECTPRIMARY,SUBQUERY
「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景

文章插图
DERIVED(需要临时表 , 自然比上述效率低)
「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景

文章插图
typeTYPE含义NULLMySQL不访问任何表,索引,直接返回结果system表只有一行记录(等于系统表) , 这是const类型的特例,一般不会出现const表示通过索引一次就找到了,const 常用于primary key 或者 unique 索引(本质上都是唯一索引) 。因为只匹配一行数据 , 所以很快 。如将主键置于where列表中,MySQL 就能将该查询转换为一个常量 。const于将 "主键" 或 "唯一" 索引的所有部分与常量值进行比较eq_ref类似ref,区别在于使用的是唯一索引,使用主键的关联查询,关联查询出的记录只有一条 。常见于主键或唯一索引扫描ref非唯一性索引扫描 , 返回匹配某个单独值的所有行 。本质上也是一种索引访问,返回所有匹配某个单独值的所有行(多个)range只检索给定返回的行,使用一个索引来选择行 。where 之后出现 between,< , > , in 等操作 。indexindex 与 ALL的区别为 index 类型只是遍历了索引树 ,  通常比ALL 快, ALL 是遍历数据文件 。all将遍历全表以找到匹配的行结果值从最好到最坏以此是:

推荐阅读