EXPLAIN命令显示了mysql如何使用索引来处理select语句以及链接表。能够帮助选择更好的索引和写出更优化的查询语句。mysql
使用方法,在select语句前加上explain,如:sql
1 | explain select page_id form pic where id=1 |
头像表-pic(描述用户头像地址):优化
# | 名字 | 类型 | 空 | 额外 | 注释 |
1 | id | int(11) | 否 | AUTO_INCREMENT | 主键 |
2 | user_id | int(11) | 否 | user表id | |
3 | url | varchar(64) | 否 | 地址 |
用户表-user(描述用户信息):url
# | 名字 | 类型 | 空 | 额外 | 注释 |
1 | id | int(11) | 否 | AUTO_INCREMENT | 主键 |
2 | name | char(38) | 否 | INDEX | 名字 |
3 | desc | varchar(64) | 否 | 描述 | |
4 | create_time | int(11) | 否 | 时间 |
重点关注type和Extra列spa
显示这一行的数据是关于哪张表的orm
这是重要的列,显示链接使用了何种类型,从最好到最差常常见到的type说明以下:排序
1,system索引
const类型的特列ci
2,consttable
表最多有一个匹配行,用于比较primary key或者unique索引
explain select * form pic where id=1
3,eq_ref
对于每一个来自于前面的表的行组合,从该表中读取一行。这多是最好的联接类型,除了const类型。它用在一个索引的全部部分被联接使用而且索引是UNIQUE或PRIMARY KEY
explain select * from pic,user where pic.user_id = user.id
4,ref
链接不能基于关键字选择单个行,可能查找到多个符合条件的行。叫作ref是由于索引要跟某个参考值相比较。这个参考值或者是一个常数,或者是来自一个表里的多表查询的结果值。
explain SELECT name FROM `user` WHERE name='1';
5,ref_or_null
如同ref,可是MySQL必须在初次查找的结果里找出null条目,而后进行二次查找
以上五种是最优的
6,range
只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪一个索引。当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操做符,用常量比较关键字列时,可使用range
7,index
全表扫描,只是扫描表的时候按照索引次序进行而不是行。主要优势就是避免了排序,可是开销仍然很是大。
explain SELECT name FROM `user` WHERE name=1
8,ALL
最坏的状况,从头至尾全表扫描
explain SELECT * FROM `user` WHERE name=1
显示可能应用在这张表中的索引。若是为空,没有可能的索引,不过重要
MySQL实际从possible_key选择使用的索引。若是为NULL,则没有使用索引。不多的状况下,MYSQL会选择优化不足的索引。这种状况下,能够在SELECT语句中使用USE INDEX(indexname)来强制使用一个索引或者用IGNORE INDEX(indexname)来强制MYSQL忽略索引
使用的索引的长度。在不损失精确性的状况下,长度越短越好
显示索引的哪一列被使用了,若是可能的话,是一个常数
MYSQL认为必须检查的用来返回请求数据的行数
关于MYSQL如何解析查询的额外信息。将在表4.3中讨论,但这里能够看到的坏的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,结果是检索会很慢
1,Distinct
一旦MYSQL找到了与行相联合匹配的行,中止为当前的行组合搜索更多的行
2,Not exists
MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,就再也不搜索了
3,Range checked for each Record(index map:#)
没有找到理想的索引,所以对于从前面表中来的每个行组合,MYSQL检查使用哪一个索引,并用它来从表中返回行。这是使用索引的最慢的链接之一
4,Using filesort
看到这个的时候,查询就须要优化了。不是“使用文件索引”的含义!filesort是MySQL所实现的一种排序策略,一般在使用到排序语句ORDER BY的时候,会出现该信息。
5,Using index
仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的所有的请求列都是同一个索引的部分的时候。若是只有 Using index,说明他没有查询到数据表,只用索引表就完成了这个查询,这个叫覆盖索引。若是同时出现Using where,表明使用索引来查找读取记录, 也是能够用到索引的,可是须要查询到数据表。
6,Using temporary
看到这个的时候,查询须要优化了。这里,MYSQL须要建立一个临时表来存储结果,这一般发生在对不一样的列集进行ORDER BY上,而不是GROUP BY上Where used 使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。若是不想返回表中的所有行,而且链接类型ALL或index,这就会发生,或者是查询有问题不一样链接类型的解释(按照效率高低的顺序排序)
7,using where
表示条件查询,若是不读取表的全部数据,或不是仅仅经过索引就能够获取全部须要的数据,则会出现 Using where。若是type列是ALL或index,而没有出现该信息,则你有可能在执行错误的查询:返回全部数据。
若是EXPLAIN出现后面两个信息(Using filesort,Using temporary),而rows又比较大,一般意味着你须要调整查询语句,或者须要添加索引,总之须要尽可能消除这两个信息。