MySql执行计划
通过分析sql的执行计划,可以清晰的知道执行的sql是如何被解析的,可以得到信息包含但不局限于,表的关联顺序,可能会用到的索引,真正用到的索引,索引的长度,扫描的记录行数等等信息。
执行计划的语法
语法很简单,只要在要分析的sql前面加上explain关键字即可。
执行计划分析
大概看一下,执行计划都有哪些数据
- id 每一个查询都对应一个id
- selectType 查询类型
- table 表名
- partitions:匹配的分区信息
- type : 针对该表的访问方法
- possible_key :可能用得到的索引
- key : 实际用到的索引
- key_length : 实际用到的索引的长度
- ref:当使用索引列进行等值匹配查询时的信息
- rows:预估的需要读取的记录数
- filtered:筛选后的数据占总数的比例
- extra:额外的信息
id
id代表select的执行顺序,当涉及到关联查询,子查询,union等查询时,就会出现多个id,当Id相同时,按照由上到下的顺序执行,当id不同时,id越大的优先级越高,对应的查询优先执行。
select_type
-
simple
简单查询,仅有一个select
连接查询也算是简单查询:
-
primary
对于包含union / union all 的查询来说,最左边的查询的类型是primary
最后一列的union result出现的原因是,union会对前后两个查询的结果进行去重,所以会出现这个临时表。 -
SUBQUERY
出现子查询,且没有被优化器优化,仍然以自查询的形式执行。
type
type是一个非常重要的指标。通常决定这个sql的执行效率。从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
- system
当表中仅有一条数据,并且该表使用的存储引擎的统计数据是精确的如Myisam,那么对该表的访问就是System。 - const
当通过主键或者唯一索引进行等值匹配,而且仅有一条数据,此时的查询就是const。
- eq_ref
eq_ref出现的场景和const的类似,不过const的是在单表查询中出现,而eq_ref是出现在关联查询中的,当被驱动表是通过主键或者唯一索引进行单值匹配,那么对于被驱动表的访问就是eq_ref。
-
ref
当通过普通的二级索引与常量进行等值匹配时,那么对该表的访问就是ref。
-
index_merge
索引合并。一般情况一次查询只会走一棵B+树,但是在个别情况下,mysql会通过优化,充分利用索引,提升查询速度。
在这种情况下,mysql会将or转换为union,进而充分利用索引,因此我们也可以在写sql的时候将or转换为union。 -
range
如果通过索引筛选某些范围的区间,那么可能用到的就是range访问类型。一般就是在where语句中出现between,<,>,in等的查询。
-
index
当使用索引覆盖,但是需要将整个索引扫描一遍时,此时的访问方式就是索引覆盖。
-
all
最熟悉的全表扫描。
索引条件下推
SELECT * FROM s1 WHERE order_no > ‘z’ AND order_no LIKE ‘%a’;
例如这么一个sql,在查询的时候,order_no是可以用到索引的,但是and后面的条件不能用到索引,因此直观上首先第一个条件通过索引定位,然后回表获取到记录后,再进行第二个条件的筛选,但是回表是一个随机io,因此mysql不着急回表,首先判断是否满足第二个条件,满足的话,才进行回表。