mysql中的explain命令可以查看sql语句是否使用了索引,用了什么索引,有没有全表扫描,帮助我们优化查询语句
explain出来的信息有10列,主要介绍type、key、Extra这几个字段
查看索引: SHOW INDEX FROM 表名
key:
sql语句实际执行时使用的索引列,有时候mysql可能会选择优化效果不是最好的索引,这时我们可以在select语句中使用 force index(indexName) 强制mysql使用指定索引,或使用 ignore index(indexName) 强制mysql忽略指定索引
key_length:
通过该列可以计算出使用到的索引占得字节数。在不适用精度的情况下长度越小越好
type:
访问类型,表示数据库引擎查找表的方式,常见的type类型如下:
all:全表扫描,效率最低
EXPLAIN select * from user_info; EXPLAIN select email from user_info; -- email未加索引
index:全索引扫描,表示sql语句将会把整颗二级索引树全部扫描一遍,效率比all高一些。一般SELECT子句中查询字段为索引字段,且无WHERE子句时,type会为index。如下:
EXPLAIN select ID from user_info;
range:部分索引扫描,当查询为区间查询,且WHERE子句中查询字段为索引字段时,type为range
EXPLAIN select * from user_info where id>11;
ref:where子句中,操作符为‘=’,且where字段为非唯一索引的单表查询或联表查询
EXPLAIN select * from order_master where userid=2 --userid是非唯一索引
eq_ref:where子句中,操作符为‘=’,且where字段为唯一索引的联表查询
EXPLAIN select * from user_info u,order_master o where u.id=o.userid
const:where子句中,操作符为‘=’,且字段为唯一索引的单表查询,此时最多会匹配的一行
EXPLAIN select * from user_info where id=2;
综上,单从type字段考虑效率,const > ref_eq > ref > range > index > all
但是,我们不能仅根据type去判断两条sql的执行速度,例如type是range的查询不一定比type是index的全表查询速度快,因为type是index时不需要回表查询,而type是range时,有可能需要回表查询
Extra:额外信息
extra列会包含一些十分重要的信息,我们可以根据这些信息进行sql优化
using index:sql没有where子句,使用覆盖索引,不需要回表查询即可拿到结果
using where:需要回表查询且没有使用到下推索引
using index && using where:sql语句有where查询条件,且使用覆盖索引,不需要回表查询即可拿到结果
using index condition:需要回表查询
using index condition && using where:需要回表查询
using filesort:语句中存在order by,无法利用索引排序,消耗性能
using temporary:建立了临时表来保存中间结果,查询完成之后又要把临时表删除,会影响性能,需尽快优化(常见于排序order by、分组查询group by)
impossible hwere:where子句的值总是false,永远查不到数据,逻辑问题尽快修改
rows:
根据表统计信息及索引选用情况,大致估算出找到所需记录,需要读取的行数,越小越好