为什么要使用索引
当表记录过多,查询效率低下,通过合理的添加索引可以提高查询效率。
什么情况下不需要使用索引
- 表记录少
- 表需要频繁更新
- 查询字段使用频率表低
explain
select_type sql语句的查找类型
simple
普通查询
SELECT id FROM orders
subquery
包含子查询的外层的类型为primary
EXPLAIN SELECT (SELECT id from orders) from orders;
primary
包含子查询的 外层的第一条记录为primary
EXPLAIN SELECT (SELECT id from orders) from orders;
union union result
包含union的结果集,在union和union all语句中,因为它不需要参与查询,所以id字段为null
EXPLAIN SELECT id from orders union select id from goods;
type 索引类型
system
const 的特殊情况,只有一条记录的时候或者是空表
const
使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const
eq_ref
关键字:连接字段主键或者唯一性索引。
- 此类型通常出现在多表的 join 查询, 表示对于前表的每一个结果, 都只能匹配到后表的一行结果. 并且查询的比较操作通常是 '=', 查询效率较高.
ref
普通非唯一索引,使用“=”值健查询非主键,或者使用了最左前缀规则索引查询,关联查询的时候,关联字段都需要建立索引
range
索引范围查询,常见于使用>,<,is null,between ,in ,like等运算符的查询中。
index
关键字:条件是出现在索引树中的节点的。可能没有完全匹配索引。
- 索引全表扫描,把索引从头到尾扫一遍,常见于使用索引列就可以处理不需要读取数据文件的查询、可
以使用索引排序或者分组的查询。
all
这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录
possible_keys
此次查询中可能选用的索引
key
查询时候,真正使用的索引
key_len
用于处理查询的索引长度。只计算查询时候使用的索引长度,如果是多列索引。并且只计算where条件使用到的索引长度,排序时候使用到索引也不会计算该索引的长度
ref
如果是关联查询,被驱动表的执行计划这里会显示驱动表的关联字段
如果是条件使用的表达式或者函数,或者内部发生了隐式转换,则会显示func
如果使用了常熟或者等值查询,会显示const
rows
执行计划中估算饿的扫描行数,不精确 myisam是精确值,innodb 使用了mvcc机制,值不准确
extra关键字段
- distanct
select中使用了distanct关键字 - no tables used
- using filesort
- 排序的时候无法使用索引,常见于order by , group by
- MySQL会使用一个外部的索引排序,不是按照索引顺序排序读取
- mysql无法利用索引完成排序成为文件排序
- using index
查询的时候,不需要通过回表查询,直接通过索引记录就可以获取信息
- 表示相应的查询中,使用了覆盖索引,避免了访问表的的数据行
- 如果同时出现了using where, 说明索引被用来执行查找索引键值
- 如果没有同时出现using where, 说明索引用来读取数据,而不是用来执行查找操作
- using temporary
使用临时表存储中间结果 - using where
表示存储引擎返回的记录并不是所有的都满足查询条件,需要在server层进行过滤。
查询条件中分为限制条件和检查条件,5.6之前,存储引擎只能根据限制条件扫描数据并返回,然
后server层根据检查条件进行过滤再返回真正符合查询的数据。5.6.x之后支持ICP特性,可以把检
查条件也下推到存储引擎层,不符合检查条件和限制条件的数据,直接不读取,这样就大大减少了
存储引擎扫描的记录数量。extra列显示using index condition
索引失效分析
- 组合索引全匹配
- 遵循最左前缀原则
- 索引不要做任何的操作。计算,函数,类型转换,都会导致索引失效
- 在复合索引中,索引字段范围右侧的列,无法使用索引
- 尽量使用覆盖索引,可以避免回表操作
- 索引上不要使用不等于
- 主键字段不要判null 非主键可以判空
- 索引字段使用like的通配符不能用在开头
- 索引字段如果是字符串要加单引号
- 索引字段不要使用or