目录
查看执行计划
EXPLAIN select * from user,account where user.id=account.user_id;
select_type
1、SIMPLE:
简单的select查询,查询中不包含子查询或者union
2、PRIMARY:
查询中包含任何复杂的子部分,最外层查询则被标记为primary
3、SUBQUERY:
在select 或 where列表中包含了子查询
4、DERIVED:
在from列表中包含的子查询被标记为derived(衍生),mysql或递归执行这些子查询,把结果放在零时表里
5、UNION:
若第二个select出现在union之后,则被标记为union;若union包含在from子句的子查询中,外层select将被标记为derived
6、UNION RESULT:
从union表获取结果的select
type
type字段在 MySQL 官网文档描述如下:
The join type. For descriptions of the different types.
即连接类型,join在 MySQL 其实有很多种含义,通常一说到join大家都会联想到left join、inner join之类的,其实在每一次的sql查询都是join,这里的join我们可以理解为获取数据的方式,join type用什么样的方式来获取数据,通常情况下type字段可以很直观的体现出 MySQL 语句的性能。都有以下这些值(顺序,性能从高到低):
1. system
当表里面只有一行数据的时候就会这样,而且不管有没有索引都一样,这是const连接类型的特殊情况。
2. const
当查询只有唯一的一条记录被匹配,并且使用主键等于常数或者唯一索引等于某常数作为查询条件时, MySQL 会视查询出来的值为常数,这种类型非常快。和system不同的地方是system是表里面只有一行数据,而const有多行数据,const是只有一行数据被匹配。例如以下查询:
SELECT * FROM table_name WHERE id = 1
SELECT * FROM table_name WHERE phone = "18866666666"
以上SQL中的id字段表示主键(PRIMARY KEY),phone表示唯一索引(UNIQUE)。
3. eq_ref
对于前一个表中的每个行组合,只从该表中读取一行。除了system和const类型之外,这是最好的连接类型。只有当联接使用索引的部分都是主键或惟一非空索引时,就会出现这种类型。例如以下查询:
SELECT * FROM table1,table2 WHERE table1.id = table2.id;
4. ref
如果理解了eq_ref类型的话那么ref类型就也很好理解了,当联接使用索引的时候:
a. 不是主键
b. 不是惟一非空索引
c. 使用了最左前缀索引(包括唯一索引和主键的)
任何一种情况,就会出现这种类型,表示连接的键使用了多行。
SELECT * FROM table WHERE name = 'zhangSan'
SELECT * FROM table1,table2 WHERE table1.name = table2.name
上面的两条SQL语句中的name字段都是普通索引。
5. fulltext
使用了全文索引的情况下就会出现这种情况。
6. ref_or_null
和ref类似,但是如果当被索引的字段可以为NULL时,就又可能出现这种情况,比如说执行了以下类似的SQL语句:
SELECT * FROM table WHERE name = 'tom' OR name IS NULL
7. index_merge
使用了索引合并优化,每个索引单独使用,再通过某种算法来合并结果。
8. unique_subquery
子查询类型的eq_ref,表示子查询返回了多列,但是每一列的值都只匹配一条记录。例如执行了以下类似的SQL(user.id字段为唯一索引):
SELECT * FROM marry WHERE user_id IN( SELECT id FROM user WHERE height < 180 );
9. index_subquery
子查询类型的ref,和unique_subquery的关系类似于eq_ref和ref,表示子查询返回了多列,但是每一列都会匹配多个记录。 例如执行了以下类似的SQL (user.name字段为普通索引) :
SELECT * FROM marry WHERE name IN( SELECT name FROM user WHERE height < 180 );
10. range
表示使用了范围类型的查询,一般出现在使用了=, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE, 货 IN() 之类的字句和常量值作比较时,剧几个简单的例子:
SELECT * FROM tbl_name WHERE key_column = 10;
SELECT * FROM tbl_name WHERE key_column BETWEEN 10 and 20;
SELECT * FROM tbl_name WHERE key_column IN (10,20,30);
SELECT * FROM tbl_name WHERE key_part1 = 10 AND key_part2 IN (10,20,30);
11. index
和后面要介绍的all类型差不多,也是全表扫描,不过index有两种情况:
- 如果是覆盖索引的情况下,只扫描整个索引树,这种情况要比all类型的全表扫描要快。
- 按索引顺序扫描全表,几乎和all类型没有区别。
12. all
性能最差的类型,全表扫描。