-- 1、简单使用
explain select * from emp;
-- 2、explain扩展使用,可查看优化执行情况
explain extended select * from emp;
show warnings ;
-- 3、结合分区使用
explain partitions select * from emp;
select
的个数,分为三种情况①id相同,从上往下执行,②id不同,id越大优先级越高,越先执行③id为null最后执行(画外音:union查询id为null)SIMPLE
:简单查询。查询不包含子查询和unionPRIMARY
:复杂查询中的最外层查询SUBQUERY
:在select中的子查询,不在from中DERIVED
:在from中的子查询,数据放在临时表中UNION
和UNION RESULT
:存在union查询,union result获取结果select_type
为union result
的时候id是空的explain select (select name from dept where id = a.dept_id) deptName from (select * from emp) a union select 1;
from 子句
中有子查询时,table列是 格式,表示当前查询依赖 id=N 的查询,于是先执行 id=N 的查询,UNION RESULT
的 table 列的值为system > const > eq_ref > ref > range > index > ALL
system
表中只有一条数据,是const的特例,一般的情况下不会出现const
查询条件为primary key或者unique key的时候匹配一条数据eq_ref
primary key 或 unique key 索引的所有部分被连接
使用 ,最多只会返回一条符合条件的记录,这个是const之后最好的
链接类型了explain select * from emp a left join dept d on a.dept_id = d.id;
ref
相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行。ref
可以出现在简单的非唯一索引查询和联合的非唯一索引查询range
范围扫描通常出现在 in(), between ,> ,<, >= ,<=等操作中。使用一个索引来检索给定范围的行index
扫描全表索引,这通常比ALL快一些。(index是从索引中读取的,而all是从硬盘中读取)-- index
explain select job_id from emp ;
all
即全表扫描,意味着MySQL需要从头到尾去查找所需要的行。extra
中的using index
一致索引最大长度是768字节
,超过长度的索引会变为最左前缀。实际使用的时候需要尽可能的减少索引的长度,提高左边的识别度。因为索引占空间类型 | 描述 |
---|---|
Using index |
查询列被索引覆盖,避免回表查询,是查询性能好的表现 |
Using where |
查询列未被索引覆盖,需要回表查询 |
Using where Using index |
查询的列被索引覆盖,并且where筛选条件是索引列之一但是不是索引的前导列 ,无法通过索引查找到数据 |
Null |
查询的列未被索引覆盖,并且where筛选条件是索引的前导列,意味着用到了索引,但是部分字段未被索引覆盖,必须通过“回表”来实现,不是纯粹地用到了索引,也不是完全没用到索引 |
Using index condition |
查询列不完全被索引覆盖,where条件是前导列的一个范围 |
Using temporary |
使用临时表来处理查询,这个时候需要优化查询 |
Using filesort |
对结果使用一个外部索引排序,而不是按索引次序从表里读取行,这个时候需要优化查询 |
mysql> -- extra
mysql> -- using index
mysql> explain select job_id from emp where job_id = 1;
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
| 1 | SIMPLE | emp | ref | idx_job_id_name | idx_job_id_name | 9 | const | 3 | Using index |
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
1 row in set (0.00 sec)
mysql> -- using where
mysql> explain select * from emp where name = '1';
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | emp | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> -- Using where Using index
mysql> explain select job_id,name from emp where name = 'frank';
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+--------------------------+
| 1 | SIMPLE | emp | index | NULL | idx_job_id_name | 139 | NULL | 8 | Using where; Using index |
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
mysql> -- Null
mysql> explain select * from emp where job_id = 1;
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------+
| 1 | SIMPLE | emp | ref | idx_job_id_name | idx_job_id_name | 9 | const | 3 | NULL |
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------+
1 row in set (0.00 sec)
mysql> -- Using index condition
mysql> explain select * from emp where job_id > 100;
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------+
| 1 | SIMPLE | emp | range | idx_job_id_name | idx_job_id_name | 9 | NULL | 1 | Using index condition |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------+
1 row in set (0.00 sec)
mysql> -- Using temporary
mysql> explain select distinct name from emp ;
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+------------------------------+
| 1 | SIMPLE | emp | index | idx_job_id_name | idx_job_id_name | 139 | NULL | 8 | Using index; Using temporary |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+------------------------------+
1 row in set (0.00 sec)
mysql> -- Using filesort
mysql> explain select name from emp order by name;
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+-----------------------------+
| 1 | SIMPLE | emp | index | NULL | idx_job_id_name | 139 | NULL | 8 | Using index; Using filesort |
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)
mysql> -- 最佳左前缀法则(job_id,name)
mysql> explain select job_id from emp where job_id = 1;
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
| 1 | SIMPLE | emp | ref | idx_job_id_name | idx_job_id_name | 9 | const | 3 | Using index |
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
1 row in set (0.00 sec)
mysql> explain select job_id from emp where name = 'frank';
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+--------------------------+
| 1 | SIMPLE | emp | index | NULL | idx_job_id_name | 139 | NULL | 8 | Using where; Using index |
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
mysql> -- 不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描
mysql> explain select * from emp where job_id + 1 = 3;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | emp | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> -- 存储引擎不能使用索引中范围条件右边的列
mysql> explain select * from emp where job_id > 100 and name = 'frank';
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------+
| 1 | SIMPLE | emp | range | idx_job_id_name | idx_job_id_name | 9 | NULL | 1 | Using index condition |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------+
1 row in set (0.00 sec)
mysql> -- 尽量使用覆盖索引(只访问索引的查询(索引列包含查询列)),减少select *语句
mysql> explain select id, name, job_id,salary, dept_id from emp where job_id > 100;
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------+
| 1 | SIMPLE | emp | range | idx_job_id_name | idx_job_id_name | 9 | NULL | 1 | Using index condition |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+-----------------------+
1 row in set (0.00 sec)
mysql> explain select job_id from emp where job_id > 100;
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+--------------------------+
| 1 | SIMPLE | emp | range | idx_job_id_name | idx_job_id_name | 9 | NULL | 1 | Using where; Using index |
+----+-------------+-------+-------+-----------------+-----------------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
mysql> -- mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描(如果覆盖索引则可以显示出来)
mysql> explain select name,emp.salary from emp where job_id != 1;
+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
| 1 | SIMPLE | emp | ALL | idx_job_id_name | NULL | NULL | NULL | 8 | Using where |
+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> -- is null,is not null 也无法使用索引
mysql> explain select emp.salary,job_id,name from emp where job_id is not null;
+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
| 1 | SIMPLE | emp | ALL | idx_job_id_name | NULL | NULL | NULL | 8 | Using where |
+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> -- like以通配符开头('%abc...')mysql索引失效会变成全表扫描操作
mysql> explain select name from emp where name like 'frank%';
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+--------------------------+
| 1 | SIMPLE | emp | index | NULL | idx_job_id_name | 139 | NULL | 8 | Using where; Using index |
+----+-------------+-------+-------+---------------+-----------------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
--下面两个比较简单
mysql> -- 字符串不加单引号索引失效
mysql> -- 少用or,用它连接时很多情况下索引会失效
Explain
来查看执行计划,分析SQL,写出高效的SQL,当然如果只是上面的内容还不够大家在日常工作中使用的,接下来还有多篇关于MySQL优化,欢迎关注!欢迎可以关注spring-cloud系列
openfeign
hystrix
,也可以关注JAVA-打怪升级系列
你的点赞和关注是我创作的最大动力,有什么不足和错误的地方欢迎留言!可以微信搜索关注【小二说码】