ID列:
ID越大越先执行,ID相同按从上向下执行
TYPE列:
system>const>eq_ref>ref>rang_index>all
保证range级别,最好是ref
const:通过主键索引,最多只有一条记录
eq_ref:两个表通过主键或唯一索引关联,最多只能关联一条记录
ref:通过二级索引,select * from table,简单查询无关联
range:索引用在范围查询
index_all:全表扫描
key_len列:
类型 | 占用字节长度 |
char(n) | n字节长度 |
varchar(n) | 3n+2 |
tinyint | 1 |
smallint | 2 |
int | 4 |
bigint | 8 |
date | 3 |
timestamp | 4 |
datetime | 8 |
null | 1 |
Extra列:
类型 | 说明 |
using index | where 走索引,使用到了覆盖索引 |
using where | 没走索引及覆盖索引 |
using where, using index | 走了覆盖索引,但是不符合最左前缀原则 |
null | 走了索引,没使用覆盖索引 |
using index condition | 范围查询走了索引 |
using filesort | 走了文件排序,效率不高 |
索引使用原则:
- 最左前缀
范围后面不走索引,一定要有带头大哥,中间索引不能断
- 索引列上不要加任何操作
- 尽量是用覆盖索引(没有回表操作)
- !=,is null,is not null 不走索引
特例:
select * from test where name like 'lilei%' and age = 22 and mobile = '12345678901'
说明:在5.7版本之后会走索引,使用到了索引下推
在通过索引遍历name的同时,也过滤出了age和mobile,然后再回表查询,减少了回表次数
在5.7版本之前,遍历name完成后进行回表,然后再过滤age和mobile。
为什么范围查询不走索引下推?
可能mysql认为范围查找数据量比较大,like大部分情况下数据量是比较小的。
有时候并不一定都索引下推,还是要看数据量