提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
explain
1.概述
https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
https://dev.mysql.com/doc/refman/8.0/en/explain-output.html
2. 基本语法
3. 执行计划包含的信息
4. 数据准备
1 . 建表
CREATE TABLE s1 (
id INT AUTO_INCREMENT,
key1 VARCHAR(100),
key2 INT,
key3 VARCHAR(100),
key_part1 VARCHAR(100),
key_part2 VARCHAR(100),
key_part3 VARCHAR(100),
common_field VARCHAR(100),
PRIMARY KEY (id),
INDEX idx_key1 (key1),
UNIQUE INDEX idx_key2 (key2),
INDEX idx_key3 (key3),
INDEX idx_key_part(key_part1, key_part2, key_part3)
) ENGINE=INNODB CHARSET=utf8;
2 . 设置参数 log_bin_trust_function_creators
创建函数,假如报错,需开启如下命令:允许创建函数设置
set global log_bin_trust_function_creators=1; # 不加global只是当前窗口有效。
3 . 创建函数
DELIMITER //
CREATE FUNCTION rand_string1(n INT)
RETURNS VARCHAR(255) #该函数会返回一个字符串
BEGIN
DECLARE chars_str VARCHAR(100) DEFAULT
'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
DECLARE return_str VARCHAR(255) DEFAULT '';
DECLARE i INT DEFAULT 0;
WHILE i < n DO
SET return_str =CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));
SET i = i + 1;
END WHILE;
RETURN return_str;
END //
DELIMITER ;
4 . 创建存储过程
创建往s1表中插入数据的存储过程:
DELIMITER //
CREATE PROCEDURE insert_s1 (IN min_num INT (10),IN max_num INT (10))
BEGIN
DECLARE i INT DEFAULT 0;
SET autocommit = 0;
REPEAT
SET i = i + 1;
INSERT INTO s1 VALUES(
(min_num + i),
rand_string1(6),
(min_num + 30 * i + 5),
rand_string1(6),
rand_string1(10),
rand_string1(5),
rand_string1(10),
rand_string1(10));
UNTIL i = max_num
END REPEAT;
COMMIT;
END //
DELIMITER ;
5 . 调用存储过程
s1表数据的添加:加入1万条记录:
CALL insert_s1(10001,10000);
EXPLAIN各列作用
1.id
id:在一个大的查询语句中每个SELECT关键字都对应一个唯一的id
- 我们写的查询语句一般都以SELECT 关键字开头,比较简单的查询语句里只有一个SELECT 关键字
- 稍微复杂一点的连接查询中也只有一个SELECT 关键字
- 多个select语句
- 特殊情况
查询优化器可能对涉及子查询的查询语句进行重写,转变为多表查询的操作
例如: A表 n条记录,B表m条记录
- 表连接查询 select * from A left B on , 复杂度 n+m
- 子查询 select * from A IN (select * from B) , 复杂度 n*m
- Union去重-------会生成一张临时表
- UNION ALL
2.table:表名
查询的每一行记录都对应着一个单表
- s1:驱动表 s2:被驱动表
3.select_type
SELECT关键字对应的那个查询的类型,确定小查询在整个大查询中扮演了一个什么角色
SIMPLE`类型
- 查询语句中不包含
UNION
或者子查询的查询都算作是SIMPLE
类型
- 连接查询也算是
SIMPLE
类型
PRIMARY类型
- 对于包含
UNION
或者UNION ALL
或者子查询的大查询来说,它是由几个小查询组成的,其中最左边的那个查询的select_type
值就是PRIMARY
- 对于包含
UNION
或者UNION ALL
的大查询来说,它是由几个小查询组成的,其中除了最左边的那个小查询 以外,其余的小查询的select_type值就是
UNION MySQL
选择使用临时表来完成UNION
查询的去重工作,针对该临时表的查询的select_type就是
UNION RESULT
SUBQUERY 类型
- 如果包含子查询的查询语句不能够转为对应的
semi-join
的形式,并且该子查询是不相关子查询。该子查询的第一个SELECT
关键字代表的那个查询的select_type就是
SUBQUERY
- 如果包含子查询的查询语句不能够转为对应的
semi-join
的形式,并且该子查询是相关子查询,
则该子查询的第一个SELECT
关键字代表的那个查询的select_type就是
DEPENDENT SUBQUERY
注意的是,select_type为
DEPENDENT SUBQUERY
的查询可能会被执行多次。
- 在包含
UNION
或者UNION ALL
的大查询中,如果各个小查询都依赖于外层查询的话,那除了最左边的那个小查询之外,其余的小查询的select_type的值就是
DEPENDENT UNION。
DERIVED 类型
- 对于包含
派生表
的查询,该派生表对应的子查询的select_type
就是DERIVED
MATERIALIZED 类型
- 当查询优化器在执行包含子查询的语句时,选择将子查询物化之后与外层查询进行连接查询时,
该子查询对应的select_type
属性就是MATERIALIZED
- 子查询被转为了物化表
4. partitions (可略)
5. type ☆
system
- 当表中
只有一条记录
并且该表使用的存储引擎的统计数据是精确的,比如MyISAM、Memory,那么对该表的访问方法就是system
MyISAM 有专门一个值,来记录表记录数
CREATE TABLE t(i INT) ENGINE=MYISAM;
INSERT INTO t VALUES(1);
换成InnoDB
CREATE TABLE tt(i INT) ENGINE=INNODB;
INSERT INTO tt VALUES(1);
const
当我们根据主键或者唯一二级索引列与常数进行等值匹配时,对单表的访问方法就是
const
ref
当通过普通的二级索引列与常量进行等值匹配时来查询某个表,那么对该表的访问方法就可能是
ref
eq_ref
- 在连接查询时,如果被驱动表是通过主键或者唯一二级索引列等值匹配的方式进行访问的
- (如果该主键或者唯一二级索引是联合索引的话,所有的索引列都必须进行等值比较),则 对该被驱动表的访问方法就是
eq_ref
ref_or_null
- 当对普通二级索引进行等值匹配查询,该索引列的值也可以是
NULL
值时,那么对该表的访问方法
就可能是ref_or_null
index_merge
- 单表访问方法时在某些场景下可以使用
Intersection
、Union
、Sort-Union`这三种索引合并的方式来执行查询
unique_subquery
unique_subquery
是针对在一些包含IN
子查询的查询语句中,如果查询优化器决定将IN
子查询
转换为EXISTS
子查询,而且子查询可以使用到主键进行等值匹配的话,那么该子查询执行计划的type
列的值就是unique_subquery
range
- 如果使用索引获取某些
范围区间
的记录,那么就可能使用到range
访问方法
index
当我们可以使用索引覆盖,但需要扫描全部的索引记录时,该表的访问方法就是
index
ALL
最熟悉的全表扫描
小结
6. possible_keys和key
可能用到的索引 和 实际上使用的索引
7. key_len
- 帮你检查
是否充分的利用上了索引
,值越大越好
,主要针对于联合索引,有一定的参考意义。
8. ref
- 当使用索引列等值查询时,与索引列进行等值匹配的对象信息。
- 比如只是一个常数或者是某个列。
- 常数
- 某个列
- 函数
9. rows
预估的需要读取的记录条数,值越小越好
10. filtered
- 某个表经过搜索条件过滤后剩余记录条数的百分比
11. Extra ☆
小结
EXPLAIN的进一步使用
EXPLAIN四种输出格式
- 这里谈谈EXPLAIN的输出格式。EXPLAIN可以输出四种格式: 传统格式, JSON格式, TREE格式以及可视化输出。用户可以根据需要选择适用于自己的格式。
1. 传统格式
2. JSON格式
3. TREE格式
4. 可视化输出
SHOW WARNINGS的使用
案例: