explain 执行计划,个人纪录,便于复习,加深理解。
一、使用
EXPLAIN + 查询语句
二、查看
id:
id是sql文表执行顺序。id相同,数据表执行优先级从上到下顺序执行;id不同,则id越大,对应数据表执行优先级越高;
select_type:
查询类型,用于区分查询类型。有以下情况:SIMPLE,PRIMARY,SUBQUERY,DEPENDENT SUBQUERY,DERIVED,UNION,DEPENDENT UNION,UNION RESULT
1.SIMPLE:简单查询,查询中不包含子查询或 union 查询
2.PRIMARY:查询中包含任何复杂的子部分,最外层查询被标记为 PRIMARY
3.SUBQUERY:在 select 或 where 列表中包含了子查询
4.DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
5.DERIVED:在 from 列表中包含的子查询被标记为DERIVED(临时表或派生表)
6.UNION:两个 select 查询语句用 union 关联时,第二个 select 被标记为UNION
7.DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
8.UNION RESULT:union 临时表检索结果的 select
(注:1,2,6目前遇到过,熟悉,其他少见,待研究)
table:
检索到的表。
当有子查询时,table列显示<derivenN>,表示当前 sql 文中有子查询,当前 sql 文的查询依赖于 id = N 的查询,id = N 的查询会优先执行。当有 union 时,UNION RESULT 的 table 列的值为 <union1,2>,1和2表示参与 union 的 select行id。
type:
表访问类型或者关联类型(重要),关系到检索表时如何查找表中行数据。
访问类型,检索效率结果值从好到坏:system >const > eq_ref > ref > fulltext > ref_or_null > index_merge >unique_subquery > index_subquery > range > index > ALL
关联类型,检索效率结果值从好到坏:const、eq_ref、ref、range、index和ALL
一般来说,sql查询至少达到range级别,最好能达到ref。
1.system:表只有一行记录(等于系统表),这是const类型的特例,平时不会出现;
2.const:表示通过索引一次就找到了,const用于比较PRIMARY KEY或者UNIQUE索引。因为只需匹配一行数据,所以很快。如果将主键置于where条件中,mysql就能将该查询转换为一个const;
3.eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。primary key 或 unique key 索引的所有部分被连接使用,最多只会返回一条符合条件的记录,目前是const之外最好的关联类型,简单查询不会出现这种type。
4.ref:使用普通索引或联合索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行。
5.ref_or_null:类似ref,但是可以搜索值为null的行。
6.index_merge:使用了索引合并,即唯一索引和普通索引联合使用。
7.range:范围扫描,使用了in(),between,> 等。使用一个索引来检索给定范围的行。
8.index:Full Index Scan,index与ALL区别为index类型只遍历索引树。index与ALL虽然都是读全表,但是index是从索引中读取,而ALL是从硬盘读取。
9.ALL:Full Table Scan,遍历全表查找匹配的行。
possible_keys:
显示查询可能使用哪些索引来查找。
如果为null,则表示没有相关的索引。可以通过检查where子句是否能添加合适的索引来提高查询性能。
如果explain时出现possible_key列,但是key列显示null,这种情况是因为表中数据不多,mysql认为索引对此查询帮助不大,选择了全表查询。
key:
显示检索时实际使用了哪个索引字段。
如果未使用索引,该列值为null。可以在查询中使用 ignore index 或 force index 强制mysql忽视或使用possible_key列中的索引。
查询中如果使用了覆盖索引,则该索引仅出现在key列表中。
key_len:
表示索引中使用的字节数,查询中使用的索引的长度(最大可能长度),非实际使用长度。理论上长度越短越好。
key_len是根据表定义计算而得到的,不是通过表内检索出的;这一列显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。
key_len计算规则如下:
- 字符串
- char(n):n字节长度
- varchar(n):2字节存储字符串长度,如果是utf-8,则长度 3n + 2
- 数值类型
- tinyint:1字节
- smallint:2字节
- int:4字节
- bigint:8字节
- 时间类型
- date:3字节
- timestamp:4字节
- datetime:8字节
- 如果字段允许为 NULL,需要1字节记录是否为 NULL
索引最大长度是768字节,当字符串过长时,mysql 会做一个类似左前缀索引的处理,将前半部分的字符提取出来做索引。
ref:
显示索引的那一列被使用了,如果可能,是一个常量const。
这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),func,NULL,字段名(例:film.id)
rows:
根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数
Extra:
不适合在其他字段中显示,但是十分重要的额外信息