likes
comments
collection
share

【mysql】 索引相关知识点

作者站长头像
站长
· 阅读数 33

mysql索引

聚簇索引

也叫聚集索引,第一索引。

聚簇索引一般是主键索引,如果没有主键索引,那么就使用唯一索引,如果没有唯一索引,那么就使用唯一的row_id,这个是一个隐藏值,如果没有前面说的那些索引,每一行会自动生成row_id。

聚集索引的结构

聚集索引内部是使用B+树结构来进行构建的, 而B+树的结构为内部节点与叶子节点:

Mysql中B+树的特性

  • 我们使用的mysql存储引擎是Innodb
  • InnoDB存储引擎最小储存单元是页,一页大小就是16k
  • 每个节点的大小都是一页,这个页可以自定义,默认是16K
  • 内部节点(非叶子节点)不存储数据,只存储指针和聚簇索引的值
  • 叶子节点存储真实的数据行
  • 索引值是有序的

B+树结构类似于下图:

【mysql】 索引相关知识点

图里的data就是真实数据。

查询的效率是很高的,每一层根据二分法来寻找指定的索引值。

非聚簇索引的结构

非聚簇索引与聚簇索引类似,但是它叶子节点不存完整数据,而是存聚簇索引值。

非聚簇索引的特点

  1. 非叶子节点存储索引列的值
  2. 叶子节点存储索引列及对应的聚簇索引的值
  3. 二级索引获取除二级索引值外的数据需要走一遍聚集索引

搞懂聚簇索引和非聚簇索引的结构之后,就可以来解释一些相关知识点。

索引进行和等值,范围查询

  1. 等值查询: 去B+树叶子节点找到某一个页,然后遍历这个页,就能找到指定值。

  2. 范围查询: 先根据等值查询找到指定值, 然后往后或往前遍历数据,找到范围值。

联合索引

联合索引在B+树中的结构形如下:

假设有一个索引(a,b,c):

abc
1510
188
3812
61015
7114
1061
1062

从a开始排序,保证a总体为非递减序列; 当a相同, 保证b为非递减序列; 当b相同,保证c为非递减序列

出几道题来加深理解:

索引(a,b,c)

  1. select * from t where a = 1 and b = 3 and c = 2; 先匹配a,再匹配b,再匹配c。
  2. select * from t where a = 1 and b > 3 and c = 5; 先匹配到a, 然后在找到b大于3的部分,这个时候c是没有顺序的,因此c会匹配失效
  3. select * from t where a > 5 and b = 5 and c = 5; 先匹配a的部分,然后b是无序的,所以后面部分的索引匹配会失效。
  4. select * from t where b = 5; 会失效,因为b在(a,b,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做主键

  1. UUID无序,添加数据很容易动整个B+树,进行分裂合并。
  2. UUID字段长, 占用内存大,导致节点里面存的数据变少,树变高,IO次数增多

为什么长字段要拆成附表

page存的数据越多,树越高,导致IO次数多

转载自:https://juejin.cn/post/7283361391671427072
评论
请登录