Explain详解
使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈在select语句之前增加explain关键字,MySQL会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL注意:如果from中包含子查询,仍会执行该子查询,将结果放入临时表中
-
id
-
select_type 查询类型(简单 复杂 子查询)
-
table 查询的哪一张表
-
partitions
-
type
-
possible_keys 查询时 可能会用到的索引
-
key 实际用到的索引
-
key_len
-
ref
-
rows 可能会扫描到的行数
-
filtered
-
rows * filtered/100 可以估算出将要和explain中钱一个表进行连接的行数(前一个表指explain中id值比当前表id小的表)
-
-
extra
id
id是查询语句执行的顺序 id越大 越先执行
当id一样时 谁在前面谁先执行
select_type
sql语句的类型
-
simple
-
简单查询 查询不包含子查询和union
-
-
primary
-
复杂查询中 最外层的select
-
-
subquery
-
包含在select中的子查询(不在from子句中 在select后面的临时表)
-
-
Derived
-
衍生查询 from后面查询生成的临时表
-
type
这一列标识关联类型或访问类型 即MySQL决定如何查找表中的行,查找数据行记录的大概范围 从优至差依次为
system>const>eq_ref>ref>range>index>all
一般来说 需要保证查询能达到range级别 最好打到ref
-
NULL
-
mysql能够在优化阶段分解查询语句,在执行阶段用不着再去访问表或索引 例如: 在索引列中选取最小值 可以单独查找索引来完成 不需要再执行时访问表
-
explain select min(id) from xxx;
如上 在优化阶段只用访问索引树就能得到结果 不需要访问索引和表 效率非常高
-
const,system
-
mysql能够对查询的某部分进行优化 并将其转化成一个常量 用于主键或唯一索引的所有列与常数比较时 所以表最多有一个匹配行 读取一次 速度比较快
-
system时const的特列 表里只有一条元组匹配时为system
-
select 1 from dual;
-
eq_ref
-
在表连接时 使用主键关联或唯一索引关联 最多只会返回一条符合条件的记录 简单的select查询不会出现这种type
explain select * from a left join b on a.xxx = b.id;
-
-
ref
-
相比于eq_ref 不使用唯一索引,而是使用普通索引,索引要和某个值比较 可能会找到多个符合条件的行
#简单select查询 name是普通索引(非唯一索引) explain select * from table where name = 'xxx';
-
#关联表查询
-
range
-
范围扫面通常出现在 in(), between,>,<等操作中 使用一个索引来检索给定范围的行
explain select * from xxx where id>1;
-
-
index
-
扫描索引就能拿到结果,一般是扫描某个二级索引,这种扫描不会从索引树的根节点开始快速查找,而是对二级索引的叶子节点遍历和扫描,速度比较慢,这种查询一般为使用覆盖索引,二级索引一般比较小(不包含所有的数据) 所以扫描索引比全表扫描快
explain select * from table;
-
-
all
-
全表扫面 扫描聚簇索引的所有叶子节点 需要进行优化
-
key_len
mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。
规则
-
字符串
char(n) 3n字节
varchar(n) 3n+2字节 加的两字节用来存储字符串长度
-
数值类型
-
tinyint 1字节
-
smallint 2字节
-
int 4字节
-
bigint 8字节
-
-
如果字段允许为null 需要1字节记录是否为null
extra
展示额外信息
Using index 使用覆盖索引
覆盖索引: 一般针对的是辅助索引,整个查询结果只通过辅助索引就能拿到结果,不需要通过辅助索引找到主键,再通过主键去聚簇索引树中获取其他字段值(不需要回表)
Using where
使用where语句来处理结果,并且查询的列未被索引覆盖
(where 后的字段没有加索引)
Using index condition
查询的列不完全被索引覆盖,where条件中是一个前导列的范围
Using temporary
mysql需要创建一张临时表来处理查询 需要优化
Using filesort
采用外部排序而不是索引排序 需要优化