MySQL索引底层结构

8 篇文章 0 订阅

当数据库的数量太大,sql查询速度比较慢的时,大部分人应该都回给相关的字段添加索引,那索引是什么呢?
本文以mysql数据库为例进行相关的闲谈;

索引是什么?

索引是一种数据结构,一个高效获取数据的排好序数据结构
常见的索引数据结构:
二叉树
红黑树
Hash表
B-Tree

我们知道MySQL数据库底层默认使用的索引数据库结构是B树中的B+树;那为什么不是其他几种数据类型呢?

假设我们要存储的数据如下:

col1col2
135
217
324
445
515
660

如果我们不采用比较好的数据结构的话,数据库中查找数据时就会一条条去查询符合条件的数据;

二叉树

我们使用col2列做索引列,大致的二叉数如下:
在这里插入图片描述
那如果我们使用col1作为索引列呢?
二叉树如下:
在这里插入图片描述
我们发现如果我们使用连续递增的字段作为索引列时,二叉树就会变成一个线性表,和我们全表扫描一样,其效率也较低;
那如果采用红黑树呢?

红黑数

红黑树是每个节点都带有颜色属性(颜色为红色或黑色)的自平衡二叉查找树,满足下列性质:
1)节点是红色或黑色;
2)根节点是黑色;
3)所有叶子节点都是黑色;
4)每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点。)
5)从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。

使用col2列的红黑树结构:
在这里插入图片描述
使用col1作为索引列的红黑树如下:
在这里插入图片描述
我们知道红黑树是会旋转来维护其平衡,那为什么MySQL数据库没有采用红黑树这个数据结构呢?我们想一想,如果数据很大的时候,红黑树的高度是不是也会随之变高,那当我们查找的元素在叶子节点呢,就需要经历树的高度次的IO,效率可想而知。红黑树的高度不可控,IO查找的次数也就不可控,数据量大的情况下就不适合;那如何对红黑树进行改造,可以让存储数据量很多,又希望IO读取次数是可控的?假如我们将每个节点横向存储更多的数据,树的高度是不是也会随之降低,其B-Tree其中就采用了这种思想;

B-Tree

B-Tree:
1.叶节点具有相同的深度,叶节点的指针为空
2.所有索引元素不重复
3.节点中的数据索引从左到右递增排列

我们先看下B-Tree大概长什么样;
在这里插入图片描述
我们看到同样的数据情况下,B树的高度明显比红黑树要低,从而查询速度会要快,那为啥MySQL底层使用的不是B树而是B+树呢
我们看下B树每个节点的结构如下

0001
data
在innodb存储引擎下,在每一个节点中还会将其索引对应行的数据也进行保存;我们都知道innodb的页块大小默认为16kb,如果data空间占用比较大,那横向存储的节点是不是就越少,那是不是树的高度也是不那么可控呢,但是还会比红黑树要矮;

B+Tree(B-Tree变种)

B+Tree特性:
1.非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
2.叶子节点包含所有索引字段
3.叶子节点用指针连接,提高区间访问的性能
在这里插入图片描述
B+树对B树进行一些改变,我们结合上面的B树可以看出:
非叶子节点不存储data,这样我们横向可以存储多个节点,从而树的高度是可控的,其叶子节点包括所有索引列及对应的数据data;并且我们可以发现B树的叶子节点之间是没有指针连接的,而B+树的叶子节点指针相连;而且B+树对范围查询更加有效。
假设我们查询select * from table where col1 > 1;
如果我们使用B树结构查询的话,是需要反复从根节点到叶子节点查询的,而B+树的话,我们找出第一个符合的条件的叶子节点后,就直接使用指针查询,不需要重新从根节点开始查询;

至于MySQL默认没有选择Hash这种结构呢,大家熟悉HashMap底层结构的话就知道Hash这种数据结构会出现hash冲突问题,最重要的是我们使用Hash表这种数据结果无法支持范围查找、模糊查找等场景。

文章仅仅是介绍的主键索引在数据结构上结构,联合索引(辅助索引)可阅读:联合索引(辅助索引)在B+树的结构

MySQL 索引底层数据结构主要有 B-Tree 和 Hash 结构两大类。 ### B-Tree B-Tree 是一种自平衡的树形数据结构,主要用于数据库和其他需要快速查找、插入和删除操作的数据存储系统中。它有以下几个关键特征: 1. **节点层次**:每个节点可以有多个子节点,并允许包含多个键值对,使得数据可以在树的较高层存储,提高查询效率。 2. **最大值限制**:节点中包含的最大键的数量是由节点的最大度数(分支因子)决定的。这意味着在同一级的节点之间存在某种形式的均匀分布。 3. **排序**:所有键都按升序排列,同时其左右子节点分别存储比当前节点小和大的键值部分。 4. **平衡**:通过调整内部结点的高度,保持整棵树的平衡状态,确保所有的路径长度大致相等。 ### Hash 结构 Hash 结构用于快速定位特定键对应的值。其核心在于利用哈希函数将键转换成一个哈希码,然后用这个哈希码作为索引来直接访问存储位置。 1. **哈希表**:基本的 hash 数据结构就是一个数组,每个元素对应着一个桶。当插入新元素时,使用哈希函数计算出该元素应该存放的位置,即哈希码对应的数组下标。 2. **冲突解决**:由于不同的键可能会得到相同的哈希码,因此需要策略处理这种冲突情况,常见的解决办法包括线性探测、链地址法和二次探查等。 3. **动态调整**:为了维持性能,哈希表通常会通过调整大小或重新哈希函数等方式来应对负载增加的情况。 ### MySQL 中的索引应用 MySQL 使用 B-Tree 结构来构建其默认类型的索引(如BTREE),这使得索引具有高效搜索、插入和删除的特点。对于 Hash 索引,则在某些场景下提供更快的查找速度,尤其是在单个列上使用并且数据集不是非常庞大时。 了解索引底层数据结构有助于优化查询性能,合理设计数据库结构和查询语句,以及更好地理解和管理数据库的运行状况。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值