索引的分类与具体讲解

原理:

B树

b树(balance tree)和b+树应用在数据库索引,可以认为是m叉的多路平衡查找树,但是从理论上讲,二叉树查找速度和比较次数都是最小的,为什么不用二叉树呢?
因为我们要考虑磁盘IO的影响,它相对于内存来说是很慢的。数据库索引是存储在磁盘上的,当数据量大时,就不能把整个索引全部加载到内存了,只能逐一加载每一个磁盘页(对应索引树的节点)。所以我们要减少IO次数,对于树来说,IO次数就是树的高度,而“矮胖”就是b树的特征之一,它的每个节点最多包含m个孩子,m称为b树的阶,m的大小取决于磁盘页的大小。

一个M阶的b树具有如下几个特征:

定义任意非叶子结点最多只有M个儿子,且M>2;
根结点的儿子数为[2, M];
除根结点以外的非叶子结点的儿子数为[M/2, M],向上取整;
非叶子结点的关键字个数=儿子数-1;
所有叶子结点位于同一层;
k个关键字把节点拆成k+1段,分别指向k+1个儿子,同时满足查找树的大小关系。
有关b树的一些特性,注意与后面的b+树区分:

**1. 关键字集合分布在整颗树中;

  1. 任何一个关键字出现且只出现在一个结点中
  2. 搜索有可能在非叶子结点结束
  3. 其搜索性能等价于在关键字全集内做一次二分查找;**
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

B+树

b+树,是b树的一种变体,查询性能更好。m阶的b+树的特征:

1. 有n棵子树的非叶子结点中含有n个关键字(b树是n-1个),这些关键字不保存数据,只用来索引,所有数据都保存在叶子节点(b树是每个关键字都保存数据)

2 所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接

3 所有的非叶子结点可以看成是索引部分,结点中仅含其子树中的最大(或最小)关键字。

4 通常在b+树上有两个头指针,一个指向根结点,一个指向关键字最小的叶子结点。

5 同一个数字会在不同节点中重复出现,根节点的最大元素就是b+树的最大元素。

在这里插入图片描述

区别

**b+树的中间节点不保存数据,所以磁盘页能容纳更多节点元素,更“矮胖”;
b+树查询必须查找到叶子节点,b树只要匹配到即可不用管元素位置,因    此b+树查找更稳定(并不慢);
对于范围查找来说,b+树只需遍历叶子节点链表即可,b树却需要重复地中序遍历:**

在这里插入图片描述

在这里插入图片描述

索引分类

聚簇索引

聚簇:表示数据行和相邻的键值紧凑地存储在一起。一个表只能有一个聚簇索引
在这里插入图片描述
上图中310,202,203,101,104等等都可以想成内存地址
以E开头的都是我们自己建立的索引列的数据
在这里插入图片描述
其实像上图这样的在mysql中就是一页,innodb引擎是按页进行IO的。

mysql页的详细讲解

聚簇索引的使用条件与不适用条件

在这里插入图片描述
聚簇索引的优点:

可以把相关数据保存在一起

数据访问更快(聚集索引将索引和数据保存在同一个b-tree中)

使用覆盖索引扫描的查询可以直接使用页节点中的主键值

聚簇索引的缺点:

聚簇数据提高了IO性能,如果数据全部放在内存中,则访问的顺序就没那么重要了

插入速度严重依赖插入顺序。按主键的顺序插入是速度最快的。但如果不是按照主键顺序加载数据,则需在加载完成后最好使用optimize table重新组织一下表

更新聚簇索引列的代价很高。因为会强制innod将每个被更新的行移动到新的位置

基于聚簇索引的表在插入新行,或主键被更新导致需要移动行的时候,可能面临页分裂的问题。页分裂会导致表占用更多的磁盘空间。

聚簇索引可能导致全表扫描变慢,尤其是行比较稀疏,或由于页分裂导致数据存储不连续的时

InnoDB使用的是聚簇索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据。若对Name列进行条件搜索,则需要两个步骤:第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。第二步使用主键在主索引B+树上再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据

非聚簇索引

在这里插入图片描述

在这里插入图片描述

非聚簇索引的使用条件

在这里插入图片描述
MyISM使用的是非聚簇索引,非聚簇索引的两棵B+树看上去没什么不同,节点的结构完全一致只是存储的内容不同而已,主键索引B+树的节点存储了主键,辅助键索引B+树存储了辅助键。表数据存储在独立的地方,这两颗B+树的叶子节点都使用一个地址指向真正的表数据,对于表数据来说,这两个键没有任何差别。由于索引树是独立的,通过辅助键检索无需访问主键的索引树

聚簇索引和非聚促索引的比较

在这里插入图片描述
在这里插入图片描述

我们重点关注聚簇索引,看上去聚簇索引的效率明显要低于非聚簇索引,因为每次使用辅助索引检索都要经过两次B+树查找,这不是多此一举吗?聚簇索引的优势在哪

1 由于行数据和叶子节点存储在一起,这样主键和行数据是一起被载入内存的找到叶子节点就可以立刻将行数据返回了,如果按照主键Id来组织数据,获得数据更快。

2 辅助索引使用主键作为"指针" 而不是使用地址值作为指针的好处是,减少了当出现行移动或者数据页分裂时辅助索引的维护工作,使用主键值当作指针会让辅助索引占用更多的空间,换来的好处是InnoDB在移动行时无须更新辅助索引中的这个"指针"。也就是说行的位置(实现中通过16K的Page来定位,后面会涉及)会随着数据库里数据的修改而发生变化(前面的B+树节点分裂以及Page的分裂),使用聚簇索引就可以保证不管这个主键B+树的节点如何变化,辅助索引树都不受影响。

唯一索引

在这里插入图片描述
在这里插入图片描述

组合索引

在这里插入图片描述

反转索引

反转索引精讲

位图索引

在这里插入图片描述

在这里插入图片描述

小结

小结:我们不难发现除了位图索引之外其他的上述所讲的索引都是基于B+树实现的,可见B+树的效率是十分高的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL索引是一种数据结构,用于提高数据库的性能。它似于书籍的索引,可以帮助快速定位到特定的数据记录。 当你在数据库表中创建一个索引时,MySQL会为该列(或多列)创建一个数据结构,该结构包含索引键和指向实际数据行的指针。这样,在查询时,MySQL可以使用索引来快速定位到匹配特定条件的数据行,而不需要遍历整个表。 要讲解MySQL索引,可以按照以下步骤: 1. 确定哪些列需要创建索引:通常,你会在经常用作查询条件的列上创建索引。例如,经常用于WHERE或JOIN语句的列,或者经常用于排序和分组的列。 2. 选择合适的索引类型MySQL支持多种索引类型,如B树索引、哈希索引、全文索引等。你需要根据具体需求选择合适的索引类型。 3. 创建索引:使用CREATE INDEX语句在表上创建索引。例如,创建一个名为idx_name的B树索引:`CREATE INDEX idx_name ON table_name (column_name);` 4. 了解索引使用的原则:索引并非越多越好,因为每个索引都需要占用存储空间,并且在插入、更新和删除操作时会有一定的性能损耗。因此,需要权衡索引的数量和性能影响。 5. 监控和优化索引:定期检查索引的使用情况,根据实际情况进行调整和优化。可以使用EXPLAIN语句来分析查询计划,查看是否正确使用了索引。 总之,MySQL索引可以显著提高查询性能,但需要根据具体情况来选择和使用索引,并进行适当的监控和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值