MySQL高级-常见索引(聚簇索引/非聚簇索引/联合索引)

在学习索引的创建和如何使用索引之前,我们先来了解索引的基本概念。如常见的索引有哪些?InnoDB中B+树有哪些需要注意的?B+和和B树的区别?

一、常见索引

我们常见的索引有聚簇索引非聚簇索引联合索引

1. 聚簇索引

聚簇索引是一种物理索引,也是数据存储的一种方式,是数据在磁盘中按照主键值重新进行排序,数据在磁盘中是连续的。聚簇索引是把所有的记录全部存放在B+树的叶子节点上面。我们上一章推演的索引数据结构主要以聚簇索引为例。

1.1 特点:

  1. 聚簇索引使用主键值的大小进行记录和页的排序。
  2. 页内的记录是按照主键的大小进行排序,成一个单向链表
  3. 各个存放记录的页,也是根据用户记录的主键大小,排序成为一个双向链表
  4. 每个记录页的记录项,也是按照记录页中记录的主键大小,排序成为一个单向链表
  5. 每个记录项的页,也是根据页中的记录项的主键大小,排序成为一个双向链表
  6. B+树的每个叶子节点的数据,都是完整的记录数据,包含隐藏列。
  7. 一个表中只能由一个聚簇索引,聚簇索引不是人为创建的,默认就有。

1.2 优点和缺点

1.2.1 优点
  1. 数据查询更快,因为聚簇索引的索引和数据全都保持在一个B+树中,访问到索引后,就可以直接访问对应的索引列数据。比非聚簇索引快很多。
  2. 聚簇索引对排序查找和范围查找非常快。
  3. 聚簇索引的数据是紧密相连的,数据库不需要从多个数据模块中拿数据,减少了磁盘的io操作,因此在聚簇索引的排序规则下, 查找范围数据是非常快的。
1.2.2 缺点
  1. 聚簇索引的插入数据非常依赖主键的顺序,如果插入的顺序不是按照主键顺序插入的话,可能就会出现页分裂的情况,因此,聚簇索引最好是按照主键顺序插入才是最快的。
  2. 在聚簇索引中,对主键的更新代价是非常大的,因为更新主键,会导致记录移动,因此,主键我们最好不要去更新。
  3. 非聚簇索引的访问,需要两次索引查找,第一次是查找到主键,第二次根据主键值去查找记录。

2. 非聚簇索引

非聚簇索引也称"二级索引",指的是以非主键列创建出来的索引,生成一个新的B+树。
下图以student(id ,name,age)表中的age列作为非聚簇索引为例:
在这里插入图片描述

2.1 特点

  1. B+树中的记录,只存放了非聚簇索引的列和主键,并不是存放了索引的数据。
  2. 目录项存放的是非聚簇索引的列和页编号,而不再是主键和页编号。
  3. 页中的记录,主要是按非聚簇索引的列大小进行排序成一个单向链表
  4. 记录页,按非聚簇索引的列大小进行排序成一个双向链表
  5. 存放目录项的页,也是按照非聚簇索引列的大小排序,形成一个双向链表。
  6. 在进行数据查找的时候,需要进行回表,也就是通过非聚簇索引进行查找的时候,要用到两个B+树。
  7. 一个表中可以由多个非聚簇索引。

2.2 非聚簇索引的查找过程

  1. 比如我们查找age为20的记录,首先我们要从页30开始找,因为16<20<39,快要快速定位到页3
  2. 页3中进行查找,因为16<20<24,可以快速定位到页5
  3. 页5的记录中,通过单向链表的查找,找到记录20的记录。
  4. 由于非聚簇索引的记录存储的是非聚簇索引列主键值,索引需要根据主键值,再去聚簇索引树种,进行查询主键为5的记录。这个操作称为回表

3. 联合索引

联合索引也叫做组合索引,指的是可以为多个列建立一个索引。
例如,给age和name创建一个索引,则成为组合索引。记录先按照age的值进行排序,如果age的值有相同时,按name再进行排序。
在这里插入图片描述

3.1 特点

  1. 叶子节点中的页,每条记录都是组合索引列(age、name)+主键(id)组成。
  2. 非叶子节点中的页,每个目录项都是由组合索引列(age、name)+页编号组成。
  3. 创建组合索引只会生成一个B+树。

二、B+树注意事项

  • 数据插入的时候,是从根节点开始的:

    • 当我们为某个表创建索引时,就会为这个索引创建一个B+树的跟节点页。最开始表中没有数据时,B+树的根据地是没有记录的,也没有目录项。
    • 当我们向这张表插入数据后,数据记录都是存放在根节点的页中。
    • 随后继续向表中插入数据,此时数据还是存放在根节点的页中,当根节点的页存放不下数据时,就会把根节点的记录复制到一个新的页(页a,叶子节点),然后在这个新页的基础上分裂出一个新页(页b),把插入的数据根据主键大小存放到页a或页b中,而根节点就升级成为目录项的页。
    • 之后插入的所有数据,都会保存在和页a同层的叶子节点下,当目录项的页存放不下目录项后,就会把目录项页复制到一个新的页(页F),然后在页F的基础上分裂出一个新页(页E),把新的目录项根据主键大小存放在页F或页E中,而根节点则升级成为目录项页的上级目录项页。
  • 一个页至少存储2条数据,一个B+树只需要很少的层级就可以轻松存储数亿条记录,查询速度相当不错!这是因为B+树本质上就是一个大的多层级目录,每经过一个目录时都会过滤掉许多无效的子目录,直到最后访问到存储真实数据的目录。那如果一个大的目录中只存放一个子目录是个啥效果呢?那就是目录层级非常非常多,而且最后的那个存放真实数据的目录中只存放一条数据。所以 InnoDB 的一个数据页至少可以存放两条记录

三、B树和B+树的区别

1. B树

  • B 树的英文是 Balance Tree,也就是 多路平衡查找树。简写为 B-Tree。它的高度远小于平衡二叉树的高度。
  • 每一个节点的最多可以包含M个字节,M就是树的阶。
  • 每个节点都包含data数据和孩子节点的指针。
  • 中间节点都会包含k个孩子节点的指针和k-1个data数据。
  • 叶子节点没有孩子节点,只有k-1个data数据。
  • 假设中间节点节点的关键字为:Key[1], Key[2], …, Key[k-1],且关键字按照升序排序,即 Key[i]<Key[i+1]。此时 k-1 个关键字相当于划分了 k 个范围,也就是对应着 k 个指针,即为:P[1], P[2], …, P[k],其中 P[1] 指向关键字小于 Key[1] 的子树,P[i] 指向关键字属于 (Key[i-1], Key[i]) 的子树,P[k] 指向关键字大于 Key[k-1] 的子树。
  • B树的查找性能相当于在所有的data中,做一次二分法查找。

在这里插入图片描述

2. B+树

B+树也是一种多路查找树,是基于B树做出的改进。
在这里插入图片描述

B+ 树和 B 树的差异在于以下几点:

  1. 有 k 个孩子的节点就有 k 个关键字。也就是孩子数量 = 关键字数,而 B 树中,孩子数量 = 关键字数 +1。
  2. 非叶子节点的关键字也会同时存在在子节点中,并且是在子节点中所有关键字的最大(或最 小)。
  3. 非叶子节点仅用于索引,不保存数据记录,跟记录有关的信息都放在叶子节点中。而 B 树中, 非 叶子节点既保存索引,也保存数据记录 。
  4. 所有关键字都在叶子节点出现,叶子节点构成一个有序链表,而且叶子节点本身按照关键字的大 小从小到大顺序链接。
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值