key_len: 表示索引中使用的字节数。
可通过该列计算【查询中使用的索引的长度】,在查询结果一样的情况下,该值越小越好。 key_len显示的值为索引字段的最大可能长度,而非实际使用长度,即通过表定义计算而得,不是通过表内检索而得。 假设你建立复合索引(col1,col2),如果【通过col1条件查询】和【通过col1和col2条件查询】的结果一样,那么前者比较好,因为只需要用一个字段,key_len的值会比较小,上面也说过是通过表定义的长度来决定key_len的值。
ref: 显示key列中索引参照的值。
有两种可能的值,以及对应所代表的信息: 库名.表名.字段名 -- 表示索引参照的值是哪个库的哪个表的哪个字段; const -- 表示索引参照的值是常量,一般是where id=1这样才会出现;
rows: 根据表统计信息以及索引选用情况,大致估算出找到要查找的记录需要读取的行数。
Extra: 十分重要的额外信息。
以下为其可能的值,以及对应所代表的信息: Using filesort -- 说明mysql完全或部分没有按照你所建的索引排序,比较需要优化了。MySQL无法利用索引完成的排序操作称为“文件排序”; Using temporary-- 使用了临时表保存中间结果,mysql对查询结果排序时使用临时表。这也比较需要优化,因为临时表的创建和删除都是比较费性能的,常见于order by和group by; Using index -- 表示相应的select操作中使用了覆盖索引,避免了访问表的数据行,效率不错。如果同时出现Using where,表明索引被用来执行索引键值的查询,如果没有出现,表明索引被用来读取数据而非执行查找动作; Using where -- 使用了where过滤; Using join buffer -- 使用了连接缓存,如果总是出现这个字段,可以去配置文件中适当调大这个值; Impossible where -- where子句的值总是false,不能用来获取任何元组; Select tables optimized away -- 在没有group by子句的情况下,基于索引优化MIN/MAX操作或者对于MyISAM存储引擎优化count(*)操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即完成优化; distinct -- 优化distinct操作,在找到第一组匹配的元组后马上停止找相同值的动作。 注意: 1. 使用group by等排序时,如果有用到索引,最好严格按照索引的顺序来,比如,存在复合索引(col1,col2),排序时如果跳过col1,直接使用col2排序,会导致出现Using filesort、Using temporary等比较严重的问题。 2. 尽量使用覆盖索引,select后面的列名完全与建立的索引顺序、数量一致。这样可以直接使用索引读取数据,避免读取表的数据行。 案例最后来看一个简单的案例,我会先放题目,再放思路,最后放答案。
题目要求是写出SQL的执行顺序。
思路
首先看id列,id越大优先级越高,索引从id为4的那一行开始看,这一行的table为t2,即查询的是t2,所以最先查找的反而是最后的部分select name,id from t2。
id为3的这一行,table是t1,所以查的是select id,name from t1 where other_column='';这一行后面的Extra列的Using where同样佐证了这点。
id为2的这一行,table是t3,所以查的是select id from t3;另外,key列是primary说明用到了主键作为索引,Extra列的Using Index表示用到了覆盖索引(即索引用在了select后面)。
id为1的这一行,table是,意思是根据【id为3的那一行的查询结果】来查询(对应的你也可以看到id为3的那一行的select_type列为Derived),所以查的是select d1.name,(select id from t3)d2 from (select id,name from t1 where other_column = '') d1
id为NULL这一行,table是<union1,4>,意思是根据【id为1和4的那两行的查询结果】来实现union查询。
答案 1.select name,id from t2 2.select id,name from t1 where other_column='' 3.select id from t3 4.select d1.name,(3.result)d2 from (2.result) d1 5.(4.result) union (1.result)最后还是建议结合前面每个字段的解释,有自己的一个思考过程是最好的。
最后今天说的是如何看explain的结果。
就好像咱们控制台打印信息是为了看代码运行的情况一样,看完了,如果有bug,还要动手改的。
而我们今天只是说如何看而已,下一步,就是如何改了。