一、Explain是什么
简而言之,explain是用来查看执行计划的,使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。可以分析出查询语句或者是表结构的性能瓶颈。具体说明可以参考MySQL官网。
二、Explain能干嘛
- 表的读取顺序
- 数据读取操作的操作类型
- 哪些索引可以使用
- 哪些索引被实际使用
- 表之间的引用
- 每张表有多少行被优化器查询
三、Explain怎么用
- EXPLAIN 的使用很简单:explain+sql语句即可。
EXPLAIN select * from sys_user LEFT JOIN sys_role on sys_user.role_id = sys_role.role_id ;
- EXPLAIN的关键是看懂执行计划所包含的信息。
如下图所示为执行后的结果,首先要知道表头各个字段的含义。
Column | JSON Name | Meaning |
---|---|---|
id | select_id | The SELECT identifier |
select_type | None | The Select Type |
table | table_name | the table for the output row |
partitions | partitions | the matching partitions |
type | access_type | the join type |
possible_keys | possible_keys | the possible indexes to choose |
key | key | the index actually chosen |
key_len | key_length | the length of the chosen key |
ref | ref | the columns compare to the index |
rows | rows | Estimate of rows to be examined |
filtered | filtered | Percentage of rows filtered by table condition |
Extra | extra | Additional information |
各个字段的具体含义和使用
EXPLAIN-id
Id是什么?
该id不是主键,而是Explain分析select语句之后,得出的查询序列号,包含一组数字,用来表示该查询语句中执行select子句或者操作表的顺序。
Id的三种取值情况:
- Id相同:执行顺序自上而下,顺序执行
EXPLAIN select * from sys_user LEFT JOIN sys_role on sys_user.role_id = sys_role.role_id ;
该语句执行后的结果:
这是什么意思呢?这表明在该查询中,两张表的优先级是一致的,执行顺序就是谁在前,谁先执行,由上而下执行,也就是sys_user先查,再查sys_role
2. Id不同:如果是子查询,id的值会递增,值越大,优先级越高,越先执行。
explain select sys_user.* from sys_user where role_id = (select role_id from sys_role where role_id = 1);
3. Id有的相同有的不相同:id值越大越先执行,值相同的,从上而下顺序执行。
explain select * from (select * from sys_user limit 10) as s,sys_role where s.role_id = sys_role.role_id;
EXPLAIN-select_type
select_type是什么?
序号 | select_type | 解释 |
---|---|---|
1 | simple | 简单的查询,没有union或者子查询 |
2 | primary | 需要Union或者子查询的select语句,位于最外层的查询单元的select_type即为primary ,有且仅有一个 |
3 | union | 在select之后使用了union,第一个查询是dervied 派生表,除了第一个表外,第二个以后的表select_type都是union |
4 | dependent union | union语句中第二个select,依赖外部子查询 |
5 | subquery | 子查询中第一select |
6 | dependent subquery | 子查询中的第一个subquery,依赖于外部子查询 |
7 | devied | 派生表select(from子句中的子查询) |
EXPLAIN-table
table是什么?
显示的查询表名,如果查询使用了别名,那么这里显示的是别名,如果不涉及对数据表的操作,那么这显示为null,如果显示为尖括号括起来的就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生。如果是尖括号括起来的