最近复习看到覆盖索引的概念,有一个 Innodb 表 user(id pk,age),id 为主键,使用 EXPLAIN SELECT id from user where id=1; 可以发现使用到了覆盖索引,但是执行 EXPLAIN SELECT age from user where id=1; 时发现 并未使用到覆盖索引,查的资料都说 InnoDB 聚集索引的叶子节点存储行记录应该包含有 age 这个字段的,但是这行查询并没有用到覆盖索引,是不是我理解有误了。
1
snappyone 2020-05-07 18:21:24 +08:00 via Android
你这个表一共就 2 列还弄啥覆盖索引
|
2
Jacky23333 2020-05-07 18:22:28 +08:00 via Android 2
@snappyone 老实人
|
4
Jacky23333 2020-05-07 18:25:48 +08:00 via Android
聚集索引里面包含 age 字段跟 age 有没有加索引完全没有关系,你说的聚集索引其实只包含了 id 字段,你的 age 字段都没有索引那自然不会有索引覆盖
|
5
qmzhixu OP @Jacky23333 嗯,因为可以用到 id 找到叶节点里面的 age,按理也没有回表检索了,所以是不是覆盖索引都没区别了
|
6
qmzhixu OP @Jacky23333 只是执行计划里面的 extra 字段显示的是不是 Using index 而已
|
7
imtemp 2020-05-07 18:50:49 +08:00
覆盖索引的概念理解有差异,看看这题
https://segmentfault.com/q/1010000018998466 |
8
imtemp 2020-05-07 19:04:10 +08:00
|
9
qumingkunnan 2020-05-07 20:41:48 +08:00 via Android
索引覆盖是说通过索引查数据,然后查的数据刚好被索引包含了的意思吧?那么我理解你可以再加个字段 sex(这个字段可能加索引不太合适,只举例用),然后建立一个 age,sex 的索引,然后查询 age,sex 字段,条件用 age 或者 age,sex 。应该是满足索引覆盖的,验证下
|
10
qmzhixu OP @qumingkunnan 这种肯定是可以的,我指的是在聚集索引叶节点数据,不是其他的索引
|
11
qumingkunnan 2020-05-07 22:11:53 +08:00 via Android
@qmzhixu 接我上条回复,聚簇索引通常只是主键做索引,你说的叶子节点是聚簇索引这个存储结构的一部分,不是索引。聚簇索引是 innodb 中表的存储形式,而不仅仅是索引。
|
12
gmhdbjd 2020-05-08 00:32:51 +08:00 via Android
没赚你的 id 不是真的聚集索引
|
13
Aresxue 2020-05-08 10:11:52 +08:00
是否使用覆盖索引和 age 上面有没有索引有直接关系, 没有索引的话自然不会走覆盖索引, 而且你这个 age 还很有可能区分度 cardinality 不够或者数据量很小,CBO 发现全表扫描的 cost 反而比较小,那就直接扫全表喽
|
14
Philyu 2020-05-15 17:27:38 +08:00
age 不在索引里面,mysql 先找到索引 id=1,然后回表去找 age,当然没有索引覆盖。
|
16
Coolha 2020-05-19 16:10:27 +08:00
An index that includes all the columns retrieved by a query.
id 所构成的索引不包括 age,所以不是覆盖索引 |
17
Philyu 2020-05-19 16:13:46 +08:00
聚簇索引的一个典型例子就是主键,它直接存储数据字段,比如 id ;如果你要查 select id from xxxx where id>n
这个当然不用回表; 如果 id 是主键,另外建立了 age 的普通索引,那么 select age from xxx where id>n,是可以索引覆盖,不需要回表。 |