explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。
使用方法,在select语句前加上explain就可以了:
explain select surname,first_name form a,b where a.id=b.id
实验环境:数据库版本 5.6.22 ,引擎 InnoDB
type:这是重要的列,显示如何执行sql语句去表里查找记录的。从最好到最差的类型为:
(1)const (2)eq_reg (3)ref (4)range (5)index (6)all
从1到6效率依次变差,1最好,6最差。
(1)const:如sql语句“WHERE user_id>=125 and sid = 377 and compact_state >= 1”当where条件中只要某一单一条件使用了主键(默认唯一索引)或者自建立的唯一索引并且参数在索引中有值(如sid=111,表中必须有sid为111的记录,若没有这么一条记录,Extra列会出现“no matching row in const table”,type为null表示为找到记录,如下图),则type为const.
优化点:若字段是数字 int bigint double 等数据类型,参数尽量不要加引号,而若是char varchar 等字符串类型,最好加上引号,如下两图对比。
其中compact_code为varchar类型,且建立了一个unique类型索引,图1可以看出,正常加上引号后,type为const(常量,效率最佳),并且用到了建立的unique索引idx_code,rows为1(代表预估算需要扫描多少条记录,这个估算并不准确);
图2,去掉引号后,type为all(全表扫描,效率最差),且并未用到索引,rows为135(代表估算需要扫描135条记录)
(2)eq_reg:
如图:其中a.sid为a表的主键,b表为a表的附表,compact_id对应a.sid,这种连表查询时,即先以主键a.sid查找a表记录,找到索引树上第一个值后,再去扫描b表全部,再接着第二遍....,所以a表为eq_reg(比const差一点(const是去直接找到那一条),比ref好一点(ref为普通索引,找到第一条后还要继续找)),b表为all(全表扫描)。
(3)ref:使用到普通索引(非unique)查询非范围时出现,如compact_code = “123”,compact_code为普通索引。
(4)range:如sql语句“where 字段1 >= "a" and 字段2 >= 281 and 字段3 >= "1"”,只要其中一个字段使用了索引(不管是unique、normal、full text)或者主键,查询某一范围的数据时出现,(当然,这里排除了const的情况,即满足不了const出现的条件)
(5)index:
▇ 情况1、只查询索引列时出现(因为索引是已经排序好的,第二图已说明,实际数据并未排序好),不管索引是什么索引
▇ 情况2、order by 主键(只能是主键,即使是其他unique索引也不行,第二图已说明)
(6)all:全表扫描,从头到尾扫描整张表查找行,效率最差