一:

MySQL官网地址:
https://dev.mysql.com/doc/refman/5.7/en/explain-output.html

explain对不同版本,有稍微差距
已5.7版本为例,

5.7之后才
有partitions:
filtered :
用extend 可以显示

两个变种

1. explain extend

提供一些额外查询优化信息,需紧跟show warnings得到优化后的SQL 但不一定能执行
filter: 估算出将要和前一个表连接的行数,

2. explain partitions

显示分区的情况,分区分表情况下游

show warnings :

一个优化后的语句,不一定能执行

explain中的列

Id

不一定唯一,执行查询的顺序,数字越大,越优先
可能会相等,谁在前面谁先执行
null最后

select_type

  1. simple :
    简单查询,不包括子查询,union
  2. primary
    负责查询的最外层select
  3. subquery
    子查询 select ( ** ) 里面的查询
  4. derived
    衍生查询:from ( * )
    临时表查询
  5. union

union 第二个和随后的select

table

from 后面的名称
有子查询是,tableg格式: 格式,Id = N ,先执行Id = N的查询
有union :union result 的table 列为 1, 2表示 参与 union 的select行ID

type:

表示访问类型,如何查找表中行的,查找数据记录的大概范围
优—-> 差: system > const > eq_ref > ref > range > index > all
优化一般从all —-> range ,最好ref

NULL : 性能最高,唯一确定了

system

表示表里只有一条数据了

const

常量 ,唯一索引,主键查询的情况

eq_ref

如果是表关联,用到主键关联,或者索引key ,

ref:

用到了索引,但不是唯一,确定多条记录
或唯一索引的前缀,

range:

范围查找 > 比较,范围查找
还是会走索引,
可对结果集优化,分页之类

index

:扫描全索引拿到结果,一般扫描二级索引,
效率不一定高,需要优化的,禁止这种
从根节点遍历索引,

ALL:

效率最低的
扫描聚簇索引,
从叶子节点挨个遍历,读取数据更大

possible_keys

可能会用到哪些索引查找
如果为null,这种情况需要检测where 子句优化,一个适当的索引

key

实际采用的索引
如果是null,如果想强制使用或忽略,
查询使用:force index ,或 ignore index

key_len

用到的索引的长度
联合查询用到的key的索引列的长度
如果为null,需要1字节存储null
计算规则:

  1. 字符串: char varchar 一个数字或字符: 1个字节 ,一个汉字 三个字节
    1. char(n) :汉字长度就: 3n 字节
    2. varchar(n) 汉字: 3n+ 2 2:字符串长度
  2. 数字类型
    1. tinyint 1字节
    2. smallint : 2字节
    3. int 4字节
    4. bignint 8字节
  3. 时间累心
    1. data: 3字节
    2. timestamp: 四字节
    3. datetime : 8字节
  4. null : 允许未null 1字节

索引最大长度为768字节,mysql 会做一个类似左前缀索引处理, 把前半部分字提取处理做索引

ref列

对应联合查询关联的字段
表查找值所用到的列或常量,常见的有:const(常量),字段名(例:film.id

rows

可能会扫描多少行,预估值

extra列

额外信息

using index

覆盖索引:不是一种索引是,一种查询方式,结果集在索引树种存在,不需要再回表查询数据

using where

可优化,没用到索引,

using index condition

  1. 查询的列,不完全被索引覆盖,where 条件中是一个前导列的范围<br />一般是范围查找

using temporary

临时表,没有用到索引
没有用到索引

using filesort

文件排序,在order by语句中
把结果集加载进内存在排序,而没有用到索引

select table optimized away :

聚合函数访问索引字段

2.最左前缀法则

不要在索引是做任何操作,不然不会走索引
运算,取值,都不可以

存储引擎不能使用索引中范围条件右边的列

尽量使用覆盖索引(只访问索引的查询(索引列包含查询列)),减少 select * 语句

分析可能会走索引,底层可能不会走索引

mysql在使用不等于(!=或者<>),not in ,not exists 的时候无法使用索引会导致全表扫描
< 小于、 > 大于、 <=、>= 这些,mysql内部优化器会根据检索比例、表大小等多个因素整体评估是否使用索引


.is null,is not null 一般情况下也无法使用索引

like以通配符开头(’$abc…’)mysql索引失效会变成全表扫描操作

字符串不加单引号索引失效

少用or或in,用它查询时,mysql不一定使用索引,mysql内部优化器会根据检索比例、表大小等多个因素整体评
估是否使用索引,详见范围查询优化


范围查询优化
就是缩小查找的范围
问题:解决like’%字符串%’索引不被使用的方法?
1使用覆盖索引,查询字段必须是建立覆盖索引字段
2如果不能使用覆盖索引则可能需要借助搜索引擎

总结

1650979421(1).pnglike KK%相当于=常量,%KK和%KK% 相当于范围