select_type: 标识SELECT的类型,常见取值有SIMPLE(简单表,即不使用表连接或者子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(子查询中的第一个SELECT)等;
table:输出结果集的表
rows:需要扫描的行数
Extra:看到Using temporary 代表使用了临时表
Using Filesort 证明使用了系效率的排序
type:标识MySQL在表中找到所需行的方式,或者叫访问类型,常见类型如下(从上至下,性能有最差到最好):
(1)type=ALL,全表扫描
(2)type=index,索引全扫描
(3)type=range,索引范围扫描,常见于<、>、between等操作符
(4)type=ref,使用非唯一索引扫描,返回匹配某个单独值的记录行
(5)type=eq_ref,类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配
(1)列类型是字符串,查询条件未加引号
(2)未使用该列作为查询条件
(3)使用like时通配符在前
(4)在查询条件中使用OR,但是OR前后的条件列并不是全部有索引
(5)对索引列进行函数运算
(6)联合索引ABC问题,匹配最左前缀,即查询条件只包含了BC的时候,无法使用联合索引
(1)MySQL支持两种方式的排序filesort和index,Using index是指MySQL扫描索引本身完成排序。index效率高,filesort效率低。
如果order by的条件不在索引列上,就会产生Using filesort。
在使用order by时select尽量不要使用*,而是只查询自己需要的字段
(2)where条件和order by使用相同的索引
(3) order by的字段都是升序或者都是降序
(4)order by多个字段时,建立联合索引,并order by后面字段的顺序跟联合索引顺序一致
(1)要尽量避免临时表,或者减少临时表数据行数;
如果GROUP BY 的列没有索引,产生临时表.
如果GROUP BY时,SELECT的列不止GROUP BY列一个,并且GROUP BY的列不是主键 ,产生临时表.
如果GROUP BY的列有索引,ORDER BY的列没索引.产生临时表.
如果GROUP BY的列和ORDER BY的列不一样,即使都有索引也会产生临时表.
如果GROUP BY或ORDER BY的列不是来自JOIN语句第一个表.会产生临时表.
如果DISTINCT 和 ORDER BY的列没有索引,产生临时表.
(2) 多使用连接(JOIN)来替代子查询,JOIN的效率更高,在符合一定规范情况下,JOIN的操作不会使得mysql产生临时表
对OR条件左右所有列都要添加索引,才能使得索引生效
(1) limit语句的查询时间与起始记录的位置成正比
mysql的limit语句是很方便,但是对记录很多的表并不适合直接使用
(2)优化limit
利用覆盖索引,即select的所有关键字列都是索引列
实际应用其实可以灵活为拆成子查询形式,如下例:
优化前:select * from student limit 79634, 20;
优化后:SELECT * FROM student a JOIN (select id from student limit 79634, 20) b ON a.ID = b.id;