一、Explain简介
使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句。分析你的查询语句或是表结构的性能瓶颈
通过EXPLAIN,我们可以分析出以下结果:
- 表的读取顺序
- 哪些索引被实际使用到
- 数据读取操作的操作类型
- 表有大约有多少行被优化器查询
用法:在select语句前添加explain
二、Explain分析
1、id
select查询的序列,表示查询中执行select子句或操作表的顺序。id列越大执行优先级越高
2、select_typ
用来表示查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询
- SIMPLE: 简单的select查询,查询中不包含子查询或者UNION
- PRIMARY: 查询中若包含任何复杂的子部分,最外层查询则被标记为PRIMARY
- SUBQUERY :在SELECT或WHERE列表中包含了子查询
- DERIVED: 在FROM列表中包含的子查询被标记为DERIVED(衍生),MySQL会递归执行这些子查询,把结果放在临时表中
- UNION:在 union 中的第二个和随后的 select
3、 table
表示 explain 的一行正在访问哪个表
4、type
表示的是查询使用了哪种类型;type包含的类型,依次从最优到最差分别
system > const > eq_ref > ref > range > index > ALL
一般来说,得保证查询达到range级别,最好达到ref
system:
表只有一行记录,这是const类型的特例,平时不会出现
const:
const用于比较主键索引或唯一索引。只要通过索引一次就找到了,只匹配一行数据
eq_ref:
主键索引 或 唯一索引的所有部分被连接使用 ,最多只会返回一条符合条件的记录
ref:
对比 eq_ref,使用普通索引或者唯一性索引的部分前缀,可能会找到多条记录
index:
扫描普通索引,这种扫描不会从索引树根节点开始快速查找,而是直接对二级索引的叶子节点进行遍历,速度还是比较慢的。二级索引一般比较小,所以这种通常比ALL快一些
ALL:
全表扫描,扫描聚簇索引的所有叶子节点。效率最慢,这时候就需要增加索引来进行优化
explain select * from actor;
5、possible_keys
6、key
7、key_len
显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列
key_len计算规则如下:
字符串,char(n)和varchar(n),5.0.3以后版本中,n均代表字符数,而不是字节数,如果是utf-8,一个数字
或字母占1个字节,一个汉字占3个字节
char(n):如果存汉字长度就是 3n 字节
varchar(n):如果存汉字则长度是 3n + 2 字节,加的2字节用来存储字符串长度,因为varchar是变长字符串
数值类型
tinyint:1字节
smallint:2字节
int:4字节
bigint:8字节
时间类型
date:3字节
timestamp:4字节
datetime:8字节
如果字段允许为 NULL,需要1字节记录是否为 NULL
索引最大长度是768字节,当字符串过长时,mysql会做一个类似左前缀索引的处理,将前半部分的字符提取出来做引。
8、ref
9、rows
10、Extra
展示的是额外信息
- Using index:使用覆盖索引
- Using where:使用 where 语句来处理结果,并且查询的列未被索引覆盖;表示优化器需要通过索引回表查询数据
- Using index condition:查询的列不完全被索引覆盖,where条件中是一个前导列的范围;
- Using temporary:mysql需要创建一张临时表来处理查询。出现这种情况一般是要进行优化的,首先是想到用索引来优化。
- Using filesort:将用外部排序而不是索引排序,数据较小时从内存排序,否则需要在磁盘完成排序。这种情况下一般也是要考虑使用索引来优化的。
- Select tables optimized away:使用某些聚合函数(比如 max、min)来访问存在索引的某个字段是
三、索引用法
- 最左前缀法则
- 不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描
- 存储引擎不能使用索引中范围条件右边的列
- 尽量使用覆盖索引(只访问索引的查询(索引列包含查询列)),减少 select * 语句
- is null,is not null 一般情况下也无法使用索引
- mysql在使用不等于(!=或者<>),not in ,not exists 的时候无法使用索引会导致全表扫描< 小于、 > 大于、 <=、>= 这些,mysql内部优化器会根据检索比例、表大小等多个因素整体评估是否使用索引