MySQL索引分析_01
zhaolengquan Lv3

表结构如下

表名为T,主键是id 自增, 新建索引name.

1
2
3
4
5
6
7
8
CREATE TABLE `T` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int DEFAULT NULL,
`adress` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `test` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

using Index

1
EXPLAIN SELECT id from t where name ='lisi';

使用了覆盖索引 要查的id 就在name索引的叶子结点上

using where

在使用索引的情况下,需要回表查询数据

using where & using Index

1
EXPLAIN SELECT id from t where name LIKE 'li%';

使用了索引,所需要的数据在索引列上都能找到, 不需要回表操作

using Index condition

1
EXPLAIN SELECT * from t where name LIKE 'li%';

虽然使用了索引,但是还需要回表查询数据

索引下推

在MySQL5.6以后引入新特性 索引下推

1
2
3
CREATE INDEX test2 ON T (name,age)

EXPLAIN SELECT * from t WHERE name like 'li%' AND age =10

在MySQL5.6版本以前 上述SQL执行流程:

因为name和age是联合索引,但是因为name是范围查询(> < between like) 根据name排序之后age索引就失效了 所以就带着id去回表查询age是否复合条件

和下图(列名不同)但原理相同

image-20220313170009359

MySQL5.6以后引入索引下推SQL执行流程是

image-20220313165927674
在根据name查询以后,InnoDB 在 (name,age) 索引内部就判断了 age 是否等于 10,对于不等于 10 的记录,直接判断并跳过。在我们的这个例子中,只需要对 ID4、ID5 这两条记录回表取数据判断,就只需要回表 2 次。

 Comments