mysql索引
聚簇索引
也叫聚集索引,第一索引。
聚簇索引一般是主键索引,如果没有主键索引,那么就使用唯一索引,如果没有唯一索引,那么就使用唯一的row_id,这个是一个隐藏值,如果没有前面说的那些索引,每一行会自动生成row_id。
聚集索引的结构
聚集索引内部是使用B+树结构来进行构建的, 而B+树的结构为内部节点与叶子节点:
Mysql中B+树的特性
- 我们使用的mysql存储引擎是Innodb
- InnoDB存储引擎最小储存单元是页,一页大小就是16k
- 每个节点的大小都是一页,这个页可以自定义,默认是16K
- 内部节点(非叶子节点)不存储数据,只存储指针和聚簇索引的值
- 叶子节点存储真实的数据行
- 索引值是有序的
B+树结构类似于下图:
图里的data就是真实数据。
查询的效率是很高的,每一层根据二分法来寻找指定的索引值。
非聚簇索引的结构
非聚簇索引与聚簇索引类似,但是它叶子节点不存完整数据,而是存聚簇索引值。
非聚簇索引的特点
搞懂聚簇索引和非聚簇索引的结构之后,就可以来解释一些相关知识点。
索引进行和等值,范围查询
等值查询: 去B+树叶子节点找到某一个页,然后遍历这个页,就能找到指定值。
范围查询: 先根据等值查询找到指定值, 然后往后或往前遍历数据,找到范围值。
联合索引
联合索引在B+树中的结构形如下:
假设有一个索引(a,b,c):
a | b | c |
---|---|---|
1 | 5 | 10 |
1 | 8 | 8 |
3 | 8 | 12 |
6 | 10 | 15 |
7 | 11 | 4 |
10 | 6 | 1 |
10 | 6 | 2 |
从a开始排序,保证a总体为非递减序列; 当a相同, 保证b为非递减序列; 当b相同,保证c为非递减序列
出几道题来加深理解:
索引(a,b,c)
先匹配a,再匹配b,再匹配c。
先匹配到a, 然后在找到b大于3的部分,这个时候c是没有顺序的,因此c会匹配失效
先匹配a的部分,然后b是无序的,所以后面部分的索引匹配会失效。
索引覆盖
比如有索引(a,b), 我查找 select a,b from t where a = 1 and b = 2
;
索引覆盖: 当我们使用二级索引时,所要查找的列刚好被包含在二级索引中,我就不用去聚集索引找数据了。
这就叫索引覆盖。
回表
什么是回表,回表是一种操作,当上面的索引覆盖失效了的时候,就会进行回表操作。
比如有索引(a, b), 我执行select a,b,c from t where a = 1 and b = 2
, 这个时候会去二级索引获取查a, b。
但是我二级索引里面并没有c的数据,因此二级索引拿到聚集索引的值,去聚集索引里面走一遍,获取数据。
为什么不建议使用UUID做主键
为什么长字段要拆成附表
page存的数据越多,树越高,导致IO次数多