MySql进阶索引篇01——深度讲解索引的数据结构:B+树(三)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL DuckDB 分析主实例,集群系列 8核16GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 深度讲解索引的数据结构:B+树

5.索引的代价

索引的代价主要是空间与时间代价。


空间上:创建索引需要存储空间。一个数据页的存储空间是16kb,如果一棵B+树有很多数据页,将会消耗较大的存储空间。

时间上:进行数据的增删改操作,同时需要对索引进行维护。主要是页面移动、页面回收、页分裂等代价。

后面的博客中,我们也将一起学习在哪些字段上适合创建索引。

6.B+树与常见的查找数据结构对比

Mysql索引的作用就是减少I/O次数,从而实现数据查找速度的提升。因此我们将以这个作为目标深入对比Hash索引,ALV树,B树和B+树,从而剖析为什么要选择B+树作为Mysql的索引底层数据结构。


6.1 Hash结构

一般提到要加快查找的速度,我们都会考虑两种数据结构:树和哈希。哈希算法的查找效率很高,可以很快的定位到数据的具体位置,通常1次检索,时间复杂度平均为

O(log2n)

而B+树还需要多次I/O,时间复杂度为O(n)


HashMap就是典型的Hash算法应用实例,下图展示了HashMap的数据结构。

哈希算法可以通过计算使一个key对应唯一value。这样我们就可以通过哈希算法计算数据应该存储的地址,把一个数据映射到一个地址。

但有时候,可能会出现两个key计算得到的地址相同的情况,我们称之为碰撞。这时我们

可以通过链接法解决。

如下Demo01是采用普通算法进行搜索,输出时间是1604ms.

public class Demo01 {
    public static void main(String[] args) {
        int [] arr = new int [100000];
       for (int i = 0; i < 100000; i++) {
            arr[i] = i ;
        }
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) { // search 10000 times
            int temp = i;
            for (int j = 0; j < arr.length; j++) {
                if(temp ==  arr[j]) {
                    break;
                }
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("cost " +(end - start) + " ms.");
    }
}

下面算法则花费时间9ms,显然hash算法的查找效率比全表扫描快很多

public class Demo02 {
    public static void main(String[] args) {
        HashSet set = new HashSet(100000);
        int [] arr = new int [100000];
        for (int i = 0; i < 100000; i++) {
            set.add(i);
        }
        long start = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) { // search 10000 times
            int temp = i;
            set.contains(temp);
        }
        long end = System.currentTimeMillis();
        System.out.println("cost " +(end - start) + " ms.");
    }
}

既然hash算法的查询效率这么高,为什么InnoDB、MyISam的索引结构要设计成为树型解构呢?


hash算法主要适用于等值判断(==,In查询),对于范围查询,还是只能通过全表扫描来完成,时间复杂度将会退化为O(n).

Hash算法存储元素是无序的,如果需要进行OrderBy等操作无法完成。

Hash算法不适合进行联合索引的查询。

当索引列重复元素较多时(比如性别),会造成大量的哈希冲突,解决哈希冲突将导致效率较低,查找效率也会变低。

总结来说,索引操作并不是只进行等值判断,或者重复元素较多的列,不适合使用hash索引。

索引引擎对于hash索引的支持情况如下图。

hash结构的索引适用于key-value型的数据库,Redis是现在很火的非关系型数据库,它的底层核心就是hash索引。Mysql中如果需要频繁的对索引进行等值判断,可以考虑使用Memory引擎。


另外,InnoDB虽然不支持Hash结构的索引,但是它提供了自适应哈希索引(Adapter Hash Index).如果某个数据页经常被访问,其地址就会被存储到哈希表中,这样下次访问时就可以直接找到这个页面的位置,这也使B+树具备了hash索引的优点。其过程可以参考下图理解。

可以通过如下命令查看数据库中是否开启了自适应hash索引。

6.2 二叉搜索树

二叉搜索树具有如下特点:

  • 一个节点最多有两个子节点,也就是节点的度不能超过2
  • 每个节点左子结点<本节点<右子节点。

其结构可以参考下图。

二叉搜索树的查找很简单,从根节点开始查找,如果查找元素比当前节点小,则在左子树中查找,如果查找元素比当前节点大,则去右子树中找。如果相等,则返回当前节点。二分查找就是利用二叉搜索树实现的。其平均时间复杂度也是O(log2n)

但是二叉搜索树的最大时间复杂度也是O(n)

因为当数据是有序时,构建的二叉搜索树会退化为线型结构哦。

为了避免出现上面的情况,我们需要对二叉搜索树的深度进行限制,AVL树就做到了这一点。

6.3 AVL树

AVL树即平衡二叉搜索树。AVL树可以是空树,除了这种特殊情况外,它要求:

  • 左、右子树的高度差不能超过1
  • 左、右子树也都是一棵平衡二叉树

上面的平衡二叉树查找一个元素最多需要五次I/O操作,有没有办法让其查找效率更高呢?

我们可以把二叉树变成m叉树,比如同样多数量的节点,在下图的三叉树中只需要四次I/O操作就可以查找到一个元素了。

基于这种把树变矮胖,从而减少树的层数的思想,我们设计了B树。

6.4 B树

B树的英文是Blance Tree,又称为多路平衡查找树。B树的结构如下图。

我们可以观察下它的特点。上面磁盘块1中有两个元素,分别是17和35,磁盘块2的元素都小于17,磁盘块3的元素位于17与35之间,磁盘块4的元素都大于35.

在一棵B树中,子结点数量的最大值称为,上图中B树的阶为3.

我们不妨回顾下B+树,然后看看B树与B+树有何不同。

我们看到,页30的节点中存储了index和page_no,而它的子结点页10则存储了具体的记录数据。但B树的叶子节点与非叶子节点存储的信息都完全独立。换句话说,B树的节点不存在上下级关系。如果使用B树作为索引的数据结构,我们需要在每个节点中存储完整的记录信息。

B树具有如下特性。

  • 如果插入数据、删除数据导致树不平衡,会自动调整至平衡。
  • 关键字集合在整个树中,即叶子节点与非叶子节点都存放数据,搜索可能在叶子节点中结束。

6.6 B+树

B+树其实是在B树的基础上进行的改进。B+树更加适合文件索引的系统。现在总结下B树与B+树的区别。

在B+树中,一个节点有k个孩子(子结点)就有k个关键字(data),而在B树中,一个节点的孩子树=关键字数+1。

B+树非叶子节点只用于索引,不存储数据.而B树中各个节点存储的都独立存储数据。

B+树所有关键字都在叶子节点出现,并且叶子节点之间通过双向链表来彼此链接,叶子节点内的数据按照顺序使用单链表连接。


上面我们提到了B+树的中间节点只用于索引,不存储数据,这有什么好处呢?


B+树的查询效率更加稳定。每次查找的I/O次数更少。

B+树的查询时I/O次数更少,查询效率更快。因为B+树的非叶子节点只用于索引,不存储数据的信息,就可以有更多的子树,这会使其更加矮胖,也就是阶数更低,查询时I/O次数更少。

B+树的范围查询效率更高,由于B+树的叶子节点存储了所有的记录信息,并且是按照顺序排列,我们在查找时通过链表指针就可以快速进行范围查询了。


6.7 R树

另外对于地图等高维搜索空间问题一般使用R树作为索引的数据结构,MySQL不支持使用R树作为索引。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
2月前
|
Java 数据挖掘 数据处理
(Pandas)Python做数据处理必选框架之一!(一):介绍Pandas中的两个数据结构;刨析Series:如何访问数据;数据去重、取众数、总和、标准差、方差、平均值等;判断缺失值、获取索引...
Pandas 是一个开源的数据分析和数据处理库,它是基于 Python 编程语言的。 Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据(类似于Excel表格)。 Pandas 是数据科学和分析领域中常用的工具之一,它使得用户能够轻松地从各种数据源中导入数据,并对数据进行高效的操作和分析。 Pandas 主要引入了两种新的数据结构:Series 和 DataFrame。
417 0
|
5月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
5月前
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
191 4
|
5月前
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
140 2
|
6月前
|
存储 关系型数据库 MySQL
MySQL覆盖索引解释
总之,覆盖索引就像是图书馆中那些使得搜索变得极为迅速和简单的工具,一旦正确使用,就会让你的数据库查询飞快而轻便。让数据检索就像是读者在图书目录中以最快速度找到所需信息一样简便。这样的效率和速度,让覆盖索引成为数据库优化师傅们手中的尚方宝剑,既能够提升性能,又能够保持系统的整洁高效。
170 9
|
7月前
|
机器学习/深度学习 关系型数据库 MySQL
对比MySQL全文索引与常规索引的互异性
现在,你或许明白了这两种索引的差异,但任何技术决策都不应仅仅基于理论之上。你可以创建你的数据库实验环境,尝试不同类型的索引,看看它们如何影响性能,感受它们真实的力量。只有这样,你才能熟悉它们,掌握什么时候使用全文索引,什么时候使用常规索引,以适应复杂多变的业务需求。
192 12
|
3月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
151 3
|
3月前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。
|
3月前
|
关系型数据库 MySQL 分布式数据库
阿里云PolarDB云原生数据库收费价格:MySQL和PostgreSQL详细介绍
阿里云PolarDB兼容MySQL、PostgreSQL及Oracle语法,支持集中式与分布式架构。标准版2核4G年费1116元起,企业版最高性能达4核16G,支持HTAP与多级高可用,广泛应用于金融、政务、互联网等领域,TCO成本降低50%。
|
3月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。

热门文章

最新文章

推荐镜像

更多