我们都知道,检测一个sql语句最直接的办法就是在语句之前来个explain。所以,用好explain可以帮忙让自己更好的了解语句是否合理是否有值得优化和改进的地方、
explian 用法比如:explain select * from table_goods
explain之后一般会有好几个参数:
1 id
这个可以忽略
2select_type
查询的类型
SIMPLE
简单SELECT(不使用UNION或子查询)
o PRIMARY
最外面的SELECT
o UNION
UNION中的第二个或后面的SELECT语句
o DEPENDENT UNION
UNION中的第二个或后面的SELECT语句,取决于外面的查询
o UNION RESULT
UNION的结果。
o SUBQUERY
子查询中的第一个SELECT
o DEPENDENT SUBQUERY
子查询中的第一个SELECT,取决于外面的查询
o DERIVED
导出表的SELECT(FROM子句的子查询)
3table
表
4type
查询访问数据的方式,手册称之为联结方式,按照从最佳类型到最差类型如下:
system:表只有一行,是const的特例
const:最多匹配一行,多用于主键或者唯一索引匹配常数的时候,如select * from table where primary_id=1,如果使用不是主键就算只有一行也不是const
eq_ref:多用在连接表的时候,比如左连接,当左表每一行数据都只能从右表只能匹配出一行的时候就是这种类型。
ref :比如左连接,左表每一行数据都能从右表里面匹配到数据(可以不止一行)。或者比如select * from table where colum='x' colum不是主键或者唯一索 引,其实可以理解为左连接第一步的左表和where条件是等同的。都是拿来去查右表
ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。但是一般建议少在有null的列建立索引(留坑)。
index_merge:索引合并,mysql5之后允许使用多个索引,索引使用的情况根据内置的算法进行合并,当出现这种优化的时候,会显示这个。
unique_subquery: 该类型替换了下面形式的IN子查询的ref:
value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
index_subquery:
该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引:
value IN (SELECT key_column FROM single_table WHERE some_expr)range: 只检索给定范围的行,使用一个索引来选择行。 key列显示使用了哪个索引。 key_len包含所使用索引的最长关键元素。在该类型中 ref列为 NULL。
index: 使用了索引扫描来排序,即索引又拿来查找数据又拿来排序。不一定使用了覆盖索引,因为orderby的时候,是否使用索引排序和select的字段是没有关系的,但是索引覆盖是和select字段有关的
ALL: 全表扫描,应该尽量避免全表扫描
5 possible_keys
可能使用到的索引
6 key
实际使用到的索引,语句可以使用use index 强制使用某索引
7 key_len
索引的长度,可以用来计算联合索引,判断是否使用到最左原则,计算方式有空总结(坑)
8 ref
ref列显示使用哪个列或常数与key一起从表中选择行
9 rows
rows列显示MySQL认为它执行查询时必须检查的行数。通过这个也可以了解到语句的执行效率
10 Extra
包含了mysql解决查询的详细信息,也是判断语句执行效率的很好的一个参数
Distinct
Not exists
range checked for each record (index map:#)
Using filesort 使用了文件排序,需避免using filesort
Using temporary 需要建立临时表来容纳结果,orderby和groupby要努力避免文件排序和临时表
Using index 使用了覆盖索引
using where 从存储引擎返回之后在服务器层使用where条件再次过滤了数据
Using sort_union(...),Using union(...),Using intersect(...)
Using index for group-by
熟练的使用explain,了解每个重点参数的意义,每次写完语句之后都在语句在之前加上explain进行性能检测之后确定无须进一步修改之后再上线是个很好的习惯