explain 的使用和解析
一.作用
使用explain这个命令去查看一个这些SQL语句,查看查询中表的读取顺序,查询类型,可以使用的索引,正在使用的索引等,可以让我们直观去看到这个SQL语句执行的顺序,是否可以优化等
二.示例
EXPLAIN select * from vehicle_company t2 where t2.vehicle_company_id =
(select t1.vehicle_company_id from vehicle_info t1 where t1.vin = 'LGXCE6DB0H0103768')
explain select * from vehicle_info t1
left join vehicle_company t2 on(t2.vehicle_company_id = t1.vehicle_company_id)
where t1.vin = 'LGXCE6DB0H0103768'
and t2.contract_code = 'GZH'
三.解析
共计出现了十二个字段:
id: 表的执行顺序
select_type: 查询的类型
table: 读取的表
partitions: 匹配的分区
type: 表示表的连接类型
possible_keys: 表示查询时,可能使用的索引
key: 表示实际使用的索引
key_len: 索引字段的长度
ref: 列与索引的比较
rows: 表扫描的行数
filtered: 按表条件过滤的行百分比
Extra: 执行情况的描述
1.id(两种情况)
a. id 相同,执行顺序从上到下
b. id 不同,id的序号会递增,id 值越大执行优先级越高
2.select_type
a. SIMPLE: 简单查询,查询中不包含子查询或者union查询
b. PRIMARY: 查询中若包含任何复杂的子部分,最外层为PRIMARY,也就是最后加载就是PRIMARY
c. SUBQUERY: 在select 或者where 列表中包含了子查询,就会被标记为SUBQUERY
d. DERIVED: 在from列表中包含的子查询会被为DERIVED
e. UNION: 若是第二个select 出现在union 后,则会被标记为UNION,若UNION包含再from子句的查询中,外层select 将被标记为DERIVED
f. UNION RESULT: 从union表获取结果的select
3.table
显示扫描那张表的
4.partitions
5.type
表示查询所使用的的访问类型,有八种,性能从差到好(从左到右)排列
ALL -> index -> range -> ref -> eq_ref -> const -> system -> NULL
a. ALL: MySQL 将遍历全表以找到匹配的行
b. index: index与ALL 区别为index 类型只遍历索引树
c. range: 只检索给定范围的行,使用一个索引来选择行
d. ref: 表示上述表的连接匹配条件,即那些列或常量被用于查找索引列上的值
e. eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key 或者unique key作为关联条件
f. const/system:当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system
g. NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
一般来说,需保证查询至少达到range级别,最好能达到ref
6.possible_keys
被连接的表中的索引,可能一个或多个,查询涉及到的字段若存在改索引,则该索引被列出,但是不一定被使用
7.key
查询实际使用的索引,如果为NULL,则表示未使用索引,若查询中使用的覆盖索引,则改索引和查询的select 字段重叠
8.key_len
索引中所使用的字节数,可通过该列计算查询中使用的长度(key_len 显示的值为索引字段的最大可能长度,并非实际使用长度),
在保证选择性的情况下,索引长度越短越好-- 前缀索引
9.ref
列与索引的比较,表示上述表的连接匹配条件,即那些列或常量被用于查找索引上的值
10.rows
估算出找到所需记录所要读取的行数,该值越小越好
11.filtered
表示存储引擎返回的数据经过滤后,剩下多少满足条件记录数量的比例
12.Extra
a. Using filesort:表示对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取,MySQL中无法利用索引完成的排序操作称为"文件排序",出现这个尽快优化SQL,数据量大的时候很危险
例如:使用表中非索引字段排序
b. Using temporary:使用了零时表保存中间结果,常见于排序order by 和分组查询group by ,出现这种情况也要优化索引
c. Using index:表名相应的select 操作中使用覆盖索引,避免访问了表的数据行,如果同时出现using where,表名索引被用来执行索引键值的查找;如果没有同时出现using where,表名索引用来读取数据而非执行查询动作。
d. Using where: 表名使用where 过滤
e. impossible where:where子句的值总是false,不能用来获取任何元组
f. select tables optimized away:在没有group by子句的情况下,基于索引优化Min、max操作或者对于MyISAM存储引擎优化count(*),不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化。
g. distinct:优化distinct操作,在找到第一匹配的元组后即停止找同样值的动作。