你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

【MySQL系列3】MySQL执行计划EXPLAIN详细说明和举例,springboot项目运行原理

2021/12/22 14:45:20

insert into test (id, name, company, age, create_time) values(‘13’,‘张三丰’,‘jd’,‘108’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘14’,‘张一1’,‘huawei’,‘18’,‘2020-05-29 12:36:11’);

insert into test (id, name, company, age, create_time) values(‘15’,‘张二1’,‘huawei’,‘19’,‘2020-05-29 12:36:13’);

insert into test (id, name, company, age, create_time) values(‘16’,‘张三1’,‘huawei’,‘20’,‘2020-05-29 12:36:15’);

insert into test (id, name, company, age, create_time) values(‘17’,‘张四1’,‘huawei’,‘22’,‘2020-05-29 12:36:16’);

insert into test (id, name, company, age, create_time) values(‘18’,‘李一1’,‘baidu’,‘22’,‘2020-05-29 12:36:18’);

insert into test (id, name, company, age, create_time) values(‘19’,‘李二1’,‘huawei’,‘22’,‘2020-05-29 12:36:24’);

insert into test (id, name, company, age, create_time) values(‘20’,‘李三1’,‘baidu’,‘22’,‘2020-05-29 12:36:25’);

insert into test (id, name, company, age, create_time) values(‘21’,‘李四1’,‘baidu’,‘26’,‘2020-05-29 12:36:28’);

insert into test (id, name, company, age, create_time) values(‘22’,‘李五1’,‘baidu’,‘27’,‘2020-05-29 12:36:30’);

insert into test (id, name, company, age, create_time) values(‘23’,‘李六1’,‘alibaba’,‘28’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘24’,‘张三丰1’,‘jd’,‘108’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘25’,‘张三丰1’,‘jd’,‘108’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘26’,‘张三丰1’,‘jd’,‘108’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘28’,‘张二1’,‘huawei11’,‘19’,‘2020-05-29 12:36:13’);

insert into test (id, name, company, age, create_time) values(‘29’,‘张三1’,‘huawei11’,‘20’,‘2020-05-29 12:36:15’);

insert into test (id, name, company, age, create_time) values(‘30’,‘张四1’,‘huawei11’,‘22’,‘2020-05-29 12:36:16’);

insert into test (id, name, company, age, create_time) values(‘31’,‘李一1’,‘baidu11’,‘22’,‘2020-05-29 12:36:18’);

insert into test (id, name, company, age, create_time) values(‘32’,‘李二1’,‘huawei11’,‘22’,‘2020-05-29 12:36:24’);

insert into test (id, name, company, age, create_time) values(‘33’,‘李三1’,‘baidu11’,‘22’,‘2020-05-29 12:36:25’);

insert into test (id, name, company, age, create_time) values(‘34’,‘李四1’,‘baidu11’,‘26’,‘2020-05-29 12:36:28’);

insert into test (id, name, company, age, create_time) values(‘35’,‘李五1’,‘baidu11’,‘27’,‘2020-05-29 12:36:30’);

insert into test (id, name, company, age, create_time) values(‘36’,‘李六1’,‘alibaba11’,‘28’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘37’,‘张三丰1’,‘jd11’,‘108’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘38’,‘张三丰1’,‘jd11’,‘108’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘39’,‘张三丰1’,‘jd11’,‘108’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘40’,‘张一9’,‘huawei11’,‘18’,‘2020-05-29 12:36:11’);

insert into test (id, name, company, age, create_time) values(‘41’,‘张二9’,‘huawei11’,‘19’,‘2020-05-29 12:36:13’);

insert into test (id, name, company, age, create_time) values(‘42’,‘张三9’,‘huawei11’,‘20’,‘2020-05-29 12:36:15’);

insert into test (id, name, company, age, create_time) values(‘43’,‘张四9’,‘huawei11’,‘22’,‘2020-05-29 12:36:16’);

insert into test (id, name, company, age, create_time) values(‘44’,‘李一9’,‘baidu11’,‘22’,‘2020-05-29 12:36:18’);

insert into test (id, name, company, age, create_time) values(‘45’,‘李二9’,‘huawei11’,‘22’,‘2020-05-29 12:36:24’);

insert into test (id, name, company, age, create_time) values(‘46’,‘李三9’,‘baidu11’,‘22’,‘2020-05-29 12:36:25’);

insert into test (id, name, company, age, create_time) values(‘47’,‘李四9’,‘baidu11’,‘26’,‘2020-05-29 12:36:28’);

insert into test (id, name, company, age, create_time) values(‘48’,‘李五9’,‘baidu11’,‘27’,‘2020-05-29 12:36:30’);

insert into test (id, name, company, age, create_time) values(‘49’,‘李六9’,‘alibaba11’,‘28’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘50’,‘张一9’,‘huawei11’,‘18’,‘2020-05-29 12:36:11’);

insert into test (id, name, company, age, create_time) values(‘51’,‘张二9’,‘huawei11’,‘19’,‘2020-05-29 12:36:13’);

insert into test (id, name, company, age, create_time) values(‘52’,‘张三9’,‘huawei11’,‘20’,‘2020-05-29 12:36:15’);

insert into test (id, name, company, age, create_time) values(‘53’,‘张四9’,‘huawei11’,‘22’,‘2020-05-29 12:36:16’);

insert into test (id, name, company, age, create_time) values(‘54’,‘李一9’,‘baidu11’,‘22’,‘2020-05-29 12:36:18’);

insert into test (id, name, company, age, create_time) values(‘55’,‘李二9’,‘huawei11’,‘22’,‘2020-05-29 12:36:24’);

insert into test (id, name, company, age, create_time) values(‘56’,‘李三9’,‘baidu11’,‘22’,‘2020-05-29 12:36:25’);

insert into test (id, name, company, age, create_time) values(‘57’,‘李四9’,‘baidu11’,‘26’,‘2020-05-29 12:36:28’);

insert into test (id, name, company, age, create_time) values(‘58’,‘李五9’,‘baidu11’,‘27’,‘2020-05-29 12:36:30’);

insert into test (id, name, company, age, create_time) values(‘59’,‘李六9’,‘alibaba11’,‘28’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘60’,‘张一9’,‘huawei11’,‘18’,‘2020-05-29 12:36:11’);

insert into test (id, name, company, age, create_time) values(‘61’,‘张二9’,‘huawei11’,‘19’,‘2020-05-29 12:36:13’);

insert into test (id, name, company, age, create_time) values(‘62’,‘张三9’,‘huawei11’,‘20’,‘2020-05-29 12:36:15’);

insert into test (id, name, company, age, create_time) values(‘63’,‘张四9’,‘huawei11’,‘22’,‘2020-05-29 12:36:16’);

insert into test (id, name, company, age, create_time) values(‘64’,‘李一9’,‘baidu11’,‘22’,‘2020-05-29 12:36:18’);

insert into test (id, name, company, age, create_time) values(‘65’,‘李二9’,‘huawei11’,‘22’,‘2020-05-29 12:36:24’);

insert into test (id, name, company, age, create_time) values(‘66’,‘李三9’,‘baidu11’,‘22’,‘2020-05-29 12:36:25’);

insert into test (id, name, company, age, create_time) values(‘67’,‘李四9’,‘baidu11’,‘26’,‘2020-05-29 12:36:28’);

insert into test (id, name, company, age, create_time) values(‘68’,‘李五9’,‘baidu11’,‘27’,‘2020-05-29 12:36:30’);

insert into test (id, name, company, age, create_time) values(‘69’,‘李六9’,‘alibaba11’,‘28’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘70’,‘张一9’,‘huawei11’,‘18’,‘2020-05-29 12:36:11’);

insert into test (id, name, company, age, create_time) values(‘71’,‘张二9’,‘huawei11’,‘19’,‘2020-05-29 12:36:13’);

insert into test (id, name, company, age, create_time) values(‘72’,‘张三9’,‘huawei11’,‘20’,‘2020-05-29 12:36:15’);

insert into test (id, name, company, age, create_time) values(‘73’,‘张四9’,‘huawei11’,‘22’,‘2020-05-29 12:36:16’);

insert into test (id, name, company, age, create_time) values(‘74’,‘李一9’,‘baidu11’,‘22’,‘2020-05-29 12:36:18’);

insert into test (id, name, company, age, create_time) values(‘75’,‘李二9’,‘huawei11’,‘22’,‘2020-05-29 12:36:24’);

insert into test (id, name, company, age, create_time) values(‘76’,‘李三9’,‘baidu11’,‘22’,‘2020-05-29 12:36:25’);

insert into test (id, name, company, age, create_time) values(‘77’,‘李四9’,‘baidu11’,‘26’,‘2020-05-29 12:36:28’);

insert into test (id, name, company, age, create_time) values(‘78’,‘李五9’,‘baidu11’,‘27’,‘2020-05-29 12:36:30’);

insert into test (id, name, company, age, create_time) values(‘79’,‘李六9’,‘alibaba11’,‘28’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘80’,‘张一科’,‘huawei11’,‘18’,‘2020-05-29 12:36:11’);

insert into test (id, name, company, age, create_time) values(‘81’,‘张二科’,‘huawei11’,‘19’,‘2020-05-29 12:36:13’);

insert into test (id, name, company, age, create_time) values(‘82’,‘张三科’,‘huawei11’,‘20’,‘2020-05-29 12:36:15’);

insert into test (id, name, company, age, create_time) values(‘83’,‘张四科’,‘huawei11’,‘22’,‘2020-05-29 12:36:16’);

insert into test (id, name, company, age, create_time) values(‘84’,‘李一科’,‘baidu11’,‘22’,‘2020-05-29 12:36:18’);

insert into test (id, name, company, age, create_time) values(‘85’,‘李二科’,‘huawei11’,‘22’,‘2020-05-29 12:36:24’);

insert into test (id, name, company, age, create_time) values(‘86’,‘李三科’,‘baidu11’,‘22’,‘2020-05-29 12:36:25’);

insert into test (id, name, company, age, create_time) values(‘87’,‘李四科’,‘baidu11’,‘26’,‘2020-05-29 12:36:28’);

insert into test (id, name, company, age, create_time) values(‘88’,‘李五科’,‘baidu11’,‘27’,‘2020-05-29 12:36:30’);

insert into test (id, name, company, age, create_time) values(‘89’,‘李六科’,‘alibaba11’,‘28’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘90’,‘张一科’,‘huawei11’,‘18’,‘2020-05-29 12:36:11’);

insert into test (id, name, company, age, create_time) values(‘91’,‘张二科’,‘huawei11’,‘19’,‘2020-05-29 12:36:13’);

insert into test (id, name, company, age, create_time) values(‘92’,‘张三科’,‘huawei11’,‘20’,‘2020-05-29 12:36:15’);

insert into test (id, name, company, age, create_time) values(‘93’,‘张四科’,‘huawei11’,‘22’,‘2020-05-29 12:36:16’);

insert into test (id, name, company, age, create_time) values(‘94’,‘李一科’,‘baidu11’,‘22’,‘2020-05-29 12:36:18’);

insert into test (id, name, company, age, create_time) values(‘95’,‘李二科’,‘huawei11’,‘22’,‘2020-05-29 12:36:24’);

insert into test (id, name, company, age, create_time) values(‘96’,‘李三科’,‘baidu11’,‘22’,‘2020-05-29 12:36:25’);

insert into test (id, name, company, age, create_time) values(‘97’,‘李四科’,‘baidu11’,‘26’,‘2020-05-29 12:36:28’);

insert into test (id, name, company, age, create_time) values(‘98’,‘李五科’,‘baidu11’,‘27’,‘2020-05-29 12:36:30’);

insert into test (id, name, company, age, create_time) values(‘99’,‘李六科’,‘alibaba11’,‘28’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘100’,‘张一科’,‘huawei11’,‘18’,‘2020-05-29 12:36:11’);

insert into test (id, name, company, `age

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

,create_time`) values(‘101’,‘张二科’,‘huawei11’,‘19’,‘2020-05-29 12:36:13’);

insert into test (id, name, company, age, create_time) values(‘102’,‘张三科’,‘huawei11’,‘20’,‘2020-05-29 12:36:15’);

insert into test (id, name, company, age, create_time) values(‘103’,‘张四科’,‘huawei11’,‘22’,‘2020-05-29 12:36:16’);

insert into test (id, name, company, age, create_time) values(‘104’,‘李一科’,‘baidu11’,‘22’,‘2020-05-29 12:36:18’);

insert into test (id, name, company, age, create_time) values(‘105’,‘李二科’,‘huawei11’,‘22’,‘2020-05-29 12:36:24’);

insert into test (id, name, company, age, create_time) values(‘106’,‘李三科’,‘baidu11’,‘22’,‘2020-05-29 12:36:25’);

insert into test (id, name, company, age, create_time) values(‘107’,‘李四科’,‘baidu11’,‘26’,‘2020-05-29 12:36:28’);

insert into test (id, name, company, age, create_time) values(‘108’,‘李五科’,‘baidu11’,‘27’,‘2020-05-29 12:36:30’);

insert into test (id, name, company, age, create_time) values(‘109’,‘李六科’,‘alibaba11’,‘28’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘111’,‘张二科’,‘huawei11’,‘19’,‘2020-05-29 12:36:13’);

insert into test (id, name, company, age, create_time) values(‘112’,‘张三科’,‘huawei11’,‘20’,‘2020-05-29 12:36:15’);

insert into test (id, name, company, age, create_time) values(‘113’,‘张四科’,‘huawei11’,‘22’,‘2020-05-29 12:36:16’);

insert into test (id, name, company, age, create_time) values(‘114’,‘李一科’,‘baidu11’,‘22’,‘2020-05-29 12:36:18’);

insert into test (id, name, company, age, create_time) values(‘115’,‘李二科’,‘huawei11’,‘22’,‘2020-05-29 12:36:24’);

insert into test (id, name, company, age, create_time) values(‘116’,‘李三科’,‘baidu11’,‘22’,‘2020-05-29 12:36:25’);

insert into test (id, name, company, age, create_time) values(‘117’,‘李四科’,‘baidu11’,‘26’,‘2020-05-29 12:36:28’);

insert into test (id, name, company, age, create_time) values(‘118’,‘李五科’,‘baidu11’,‘27’,‘2020-05-29 12:36:30’);

insert into test (id, name, company, age, create_time) values(‘119’,‘李六科’,‘alibaba11’,‘28’,‘2020-05-29 12:36:31’);

insert into test (id, name, company, age, create_time) values(‘120’,‘张丹峰’,‘tx’,‘36’,‘2020-05-29 22:36:31’);

insert into test (id, name, company, age, create_time) values(‘121’,‘test’,‘tttt’,‘44’,‘2020-05-30 06:19:12’);

insert into test (id, name, company, age, create_time) values(‘122’,‘张一5’,‘bbaidu’,‘30’,‘2020-05-30 09:20:08’);

然后执行explain执行计划

EXPLAIN SELECT * FROM teacher

返回结果:

在这里插入图片描述

explain返回结果说明

==========================================================================

每列的含义如下**后面的字段及类型说明全部参考官网,并结合自己弱弱的英文进行翻译而来,可以算的上是最全的整理了,关注孤狼,和孤狼一起学习进步**

| 列 | 英文释义 | 中文翻译 |

| — | — | — |

| id | The SELECT identifier | id标识符 |

| select_type | The SELECT type | 查询类型 |

| table | The table for the output row | 输出行的表名 |

| partitions | The matching partitions | 匹配的分区 |

| type | The join type | 关联类型 |

| possible_keys | The possible indexes to choose | 可能选择的索引 |

| key | The index actually chosen | 最终选择使用的索引 |

| key_len | The length of the chosen key | 选中的索引的长度 |

| ref | The columns compared to the index | 与索引比较的列 |

| rows | Estimate of rows to be examined | 预估需要扫描的行数 |

| filtered | Percentage of rows filtered by table condition | 根据条件实际过滤数据百分比 |

| Extra | Additional information | 附加信息 |

id


如果id都相同,那么sql先执行的是按顺序从上到下执行,如果id不同,那么是从大到小执行,优先从大到小,也就是按照8字原则:先大后小,从上到下。当select_type出现 <unionM,N> 的时候id会显示为null。

如下面的截图中,表示MySQL最先执行的最后面的一句(从大到小),然后从第1条开始执行,直到全部执行完毕(从上到下)。

在这里插入图片描述

select_type


SELECT的类型,可以是下表中显示的任何类型。JSON名称(如适用)也会显示在表中:

| select_type | JSON名称 | 英文释义 | 中文翻译 |

| — | — | — | — |

| SIMPLE | None | Simple SELECT (not using UNION or subqueries) | 没有用到union或者子查询的简单查询语句 |

| PRIMARY | None | Outermost SELECT | 最外层的查询,即:主查询 |

| UNION | None | Second or later SELECT statement in a UNION | union查询中第二个(含)之后的查询语句 |

| DEPENDENT UNION | dependent (true) | Second or later SELECT statement in a UNION, dependent on outer query | union查询中第二个(含)之后的查询且依赖于外部查询 |

| UNION RESULT | union_result | Result of a UNION | 联合查询的结果(此时id为Null) |

| SUBQUERY | None | First SELECT in subquery | 子查询中的第一个查询 |

| DEPENDENT SUBQUERY | dependent (true) | First SELECT in subquery, dependent on outer query | 子查询中的第一个查询且依赖于外部查询 |

| DERIVED | None | Derived table | 派生表(如:select * from (select * from t) a查询语句中a表就是派生表) |

| MATERIALIZED | materialized_from_subquery | Materialized subquery | 物化子查询 |

| UNCACHEABLE SUBQUERY | cacheable (false) | A subquery for which the result cannot be cached and must be re-evaluated for each row of the outer query | 子查询的结果不能被缓存,只能被外部查询重新一行行匹配 |

| UNCACHEABLE UNION | cacheable (false) | The second or later select in a UNION that belongs to an uncacheable subquery (see UNCACHEABLE SUBQUERY) | union语句中第二个(含)以后的查询是一个UNCACHEABLE SUBQUERY查询 |

table


当前行输出的表名。

  • <unionM,N>: 表示当前行的结果是id为M和N的union的结果。

  • <\derivedN>:表示当前行的表是由id为N的查询结果的派生表。

  • <\subqueryN>: 表示当前行的结果是id为N的子查询结果。

type


描述了实际查询是如何连接表的,下面我们依据查询效率最优到最差开始逐个介绍举例:(需要注意的是,测试的时候数据不要太少了,如果数据太少可能不会出现预期效果,因为有时候数据过少MySQL就不会使用过多优化手段,转而会直接全表扫描)

system类型

系统表里面只有一行记录,这个是const类型中的特殊情况。

EXPLAIN SELECT * FROM mysql.time_zone – 这条记录是我自己写进去测试的

在这里插入图片描述

const 类型

表最多有一个匹配行,在查询开始时读取。因为只有一行,所以这一行中列的值可以被优化器的其他部分视为常量。const表非常快,因为它们只被读取一次。

const用于将主键或唯一索引的所有部分与常量值进行比较。const适用于如下查询:

SELECT * FROM tbl_name WHERE primary_key=1;

SELECT * FROM tbl_name WHERE primary_key_part1=1 AND primary_key_part2=2;

举例1:

EXPLAIN SELECT * FROM USER WHERE id=1;

在这里插入图片描述

举例2::

ALTER TABLE USER DROP PRIMARY KEY; – 删除原先主键索引

ALTER TABLE USER ADD PRIMARY KEY (id,NAME);-- 新建联合主键索引

EXPLAIN SELECT * FROM USER WHERE id=1 AND NAME=‘张一’;

在这里插入图片描述

eq_ref

对于前一个表中的每个组合,从这个表中读取一行。除了system和const类型之外,这是最好的连接类型。当使用索引的所有部分并且索引是主键或唯一非空索引时,将使用该类型。

eq_ref可以用于使用=操作符进行比较的索引列。比较值可以是常量,也可以是使用在该表之前读取的表中的列的表达式。

简单的说:就是两张表通过其中一张表的主键或者唯一非空索引进行关联时,查询结果是一对一的关系。

eq_ref适用于如下查询:

SELECT * FROM ref_table,other_table

WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table

WHERE ref_table.key_column_part1=other_table.column

AND ref_table.key_column_part2=1;

举例1:

EXPLAIN SELECT * FROM USER u,user_detail d WHERE u.detail_id=d.id

在这里插入图片描述

举例2:

ALTER TABLE user_job DROP PRIMARY KEY;-- 删除主键单列索引

ALTER TABLE user_job ADD PRIMARY KEY id_name_index(id,job_name);-- 添加联合主键索引

EXPLAIN SELECT * FROM user u,user_job j WHERE u.job_id=j.id AND job_name=‘CEO’;

在这里插入图片描述

ref

对于前一个表中的每个行组合,从这个表中读取具有匹配索引值的所有行。如果连接只使用键的最左端前缀,或者如果键不是主键或惟一索引(换句话说,如果连接不能根据键值选择单个行),则使用ref。如果使用的键只匹配几行,这是一种很好的连接类型。

这个和eq_ref最大的区别是ref一般用于普通索引的场景下,而eq_ref是用于主键或者唯一非空索引

ref适用于如下三种类型查询:

SELECT * FROM ref_table WHERE key_column=expr;

SELECT * FROM ref_table,other_table

WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table

WHERE ref_table.key_column_part1=other_table.column

AND ref_table.key_column_part2=1;

举例1:

ALTER TABLE user_detail DROP PRIMARY KEY;-- 删除主键索引

ALTER TABLE user_detail ADD INDEX id_index(id);-- 添加一个普通索引

EXPLAIN SELECT * FROM user_detail WHERE id=1

在这里插入图片描述

举例2:

EXPLAIN SELECT * FROM USER u,user_detail d WHERE u.detail_id=d.id;

在这里插入图片描述

举例3:

ALTER TABLE user_job DROP PRIMARY KEY;-- 删除联合主键索引

ALTER TABLE user_job ADD INDEX id_name_index(id,job_name);-- 添加普通的联合主键索引

EXPLAIN SELECT * FROM user u,user_job j WHERE u.job_id=j.id AND job_name=‘CEO’;

在这里插入图片描述

fulltext

这个比较简单,用到了全文索引就会出现,就不做演示了,感兴趣的可以点击这里,了解全文索引

ref_or_null

这个连接类型类似于ref,但是多了一个对空值的搜索条件。这种连接类型优化最常用于解析子查询。适用于如下查询:

SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;

举例:

ALTER TABLE user_detail MODIFY COLUMN id INT(3) DEFAULT NULL;

EXPLAIN SELECT * FROM user_detail WHERE id=‘111’ OR id IS NULL;

注意,这个例子中因为id是整型,本人这边因为反复修改索引,导致id列已经有了默认值为0,所以MySQL知道这一列没有null值,直接查询是不会出现这种类型的,故而才需要改为默认值为null

在这里插入图片描述

index_merge

索引合并访问方法检索具有多个范围扫描的行,并将其结果合并为一个。此访问方法仅合并来自单个表的索引扫描,不能跨多个表扫描。合并可以生成其底层扫描的联合、交叉或交叉的联合。

想要详细了解索引合并的概念,请点击这里。

下面几种情况可能会用到索引合并:

SELECT * FROM tbl_name WHERE key1 = 10 OR key2 = 20;

SELECT * FROM tbl_name

WHERE (key1 = 10 OR key2 = 20) AND non_key = 30;

SELECT * FROM t1, t2

WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE ‘value%’)

AND t2.key1 = t1.some_col;

SELECT * FROM t1, t2

WHERE t1.key1 = 1

AND (t2.key1 = t1.some_col OR t2.key2 = t1.some_col2);

举例1(注意test表有一个主键索引和一个普通索引):

EXPLAIN SELECT * FROM test WHERE id = 1 OR NAME=‘张三丰’

在这里插入图片描述

这里之所以会单独准备一张test表是因为其他表数据都太少了,数据少的时候全表扫描有时候会比使用其他优化措施效率更高

举例2

EXPLAIN SELECT * FROM test WHERE (id = 1 OR NAME=‘张三丰’) AND company=‘huawei’;

在这里插入图片描述

unique_subquery

这个类型替换了表单的子查询中的一些eq_ref,一般用于子查询,而且子查询只返回主键或者唯一索引:

value IN (SELECT primary_key FROM single_table WHERE some_expr)

unique_subquery只是一个索引查找函数,它完全取代了子查询以提高效率。

举例(test表和user表中id均为主键):

EXPLAIN SELECT * FROM user u WHERE id IN (SELECT id FROM test t) OR name=‘张一’

在这里插入图片描述

这里不知道各位会不会奇怪,为什么查询条件要加一个or,如果把or去掉呢?去掉之后的执行计划如下图:

在这里插入图片描述

有一个明显的区别,加了or先执行的子查询(图一中t表的查询id为2,所以先执行),而不加or,先查询的是u表(图2中id都是1,从上往下执行),所以说我们加一个or只是为了确保MySQL会先执行子查询,这样才会出现unique_subquery。

题外话:很多人查询的时候用子查询以为MySQL会先执行子查询,实际上大部分情况都是不会的,都是先执行的外层查询,再一条条记录去和子查询匹配,这也就是为什么很多人建议不要用子查询的原因,当然,这也不是绝对的,有的时候子查询的效率也会更高,所以具体的还是要视业务数据来具体分析

index_subquery

这种类型和unique_subquery非常类似,唯一不同的就是子查询中返回的不是主键或者唯一索引:

value IN (SELECT key_column FROM single_table WHERE some_expr)

举例(确保test表中name字段有一个普通索引):

EXPLAIN SELECT * FROM user u WHERE name IN (SELECT name FROM test t) OR name=‘张一’;

在这里插入图片描述

range

使用索引去检索范围内的行,输出行中的键列指示使用哪个索引。基本上是用到了以下操作符: !=, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE, or IN()。

注意:注意,这里的第一个操作符和下面的第一个语法样例,官网写的是等于,个人认为应该是不等于,如果使用=,那么key_cloumn是主键和唯一索引则是eq_ref类型,普通索引则是ref类型,没有索引则是ALL

题外话:<==>操作符相当于判断两个值是否相等,不同的是这个是可以判断null值的,即cloumn is null 等价于 column<=>null

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);

举例(其他例子就不举了,这个相对比较简单了):

EXPLAIN SELECT id,NAME FROM test WHERE id !=1;

在这里插入图片描述

index

即:Full Index Scan(全索引扫描)。当查询只使用属于单个索引的列时,MySQL可以使用这种连接类型。这种类型和ALL是差不多的,ALL是扫描全表,index是扫描全索引。index会发生在以下两种情况:

  • 使用到了覆盖索引

  • 按照索引的顺序来进行读取数据

举例1(使用覆盖索引):

EXPLAIN SELECT id,NAME FROM test;

举例2(按索引顺序读取):

EXPLAIN SELECT id FROM test;

ALL

全表扫描,最差的一种查询。不带where条件或者where条件没有使用到任何索引的情况。

NULL

不需要用到表就可以返回结果。

EXPLAIN SELECT NOW();

在这里插入图片描述

Extra