解锁高效检索技能:掌握MySQL索引数据结构的精髓

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 解锁高效检索技能:掌握MySQL索引数据结构的精髓


磁盘存储

哇,磁盘存储这个话题听起来好高大上呀!其实就是说,我们的电脑或者手机里面的数据是如何被存储的问题。我们可以把数据理解成一摞卡片,而我们的电脑或手机就是一个卡片盒子。而我们需要做的就是把这些卡片存储到盒子里面,然后需要的时候再把卡片拿出来。

但是,问题来了,如果我们的数据很多,卡片也很多的话,我们怎么才能让电脑或手机更快地找到我们需要的数据呢?这就要用到磁盘块了。所谓磁盘块,就是指硬盘上划分出来的一块一块的空间。就好比我们的卡片盒子里面,我们可以将卡片分成一叠一叠的,每一叠就是一个磁盘块。

而我们的电脑或手机在查找数据的时候,并不是只找一张卡片,而是会一次性读取整个磁盘块的数据。这就好比我们在找一张卡片的时候,不仅把这一张卡片拿出来,还把这张卡片的前后几张卡片也拿出来看看。

而当我们的电脑或手机需要查找某个数据时,它会先找到这个数据在哪个磁盘块里面,然后才能拿到这个数据。这就好比我们在找一张卡片的时候,需要先找到这张卡片在哪一叠里面,才能找到这张卡片。

但是,电脑或手机在硬盘上存储数据的时候,并不是按照我们的卡片一样,每个数据都放进一个独立的磁盘块里面。而是将一块磁盘块分成很多个小的存储单元,然后把不同的数据分别存放在不同的存储单元里面。这就好比我们的卡片盒子里面,我们把每一叠卡片分成很多小格子,不同的卡片放在不同的小格子里面。

而就像我们在找一张卡片的时候,需要先找到这张卡片在哪一叠里面,再找到这张卡片的具体位置一样。电脑或手机在找到所在的磁盘块后也需要再找到具体的存储单元,才能获取需要的数据。

但是,如果我们的数据量很大,磁盘块的数量也会很多,这样就会导致查找数据的时间变长,效率变低。为了解决这个问题,我们可以使用树形结构来存储数据。

树形结构是一种层次化的数据结构,它可以快速定位到要找的数据。树形结构中有一个叫做根节点的节点,它是整个树的顶端,相当于我们卡片盒子的盖子。而树的每个节点下面都可以有很多子节点,就好比我们卡片盒子里面的每一叠卡片。每个节点下面还可以有很多子节点,这样就形成了一棵树。

在数据库中,我们经常使用的是B树或B+树。B树中的每个节点都有对应的key和value,而B+树则是将所有的数据记录都存放在叶子节点上。而非叶子节点上只存储key信息。这样可以大大增加每个节点存储的key数量,降低树的高度,提高了数据查找的效率。

磁盘存储这个话题虽然听起来很高深,但实际上就是把我们的数据存放在电脑或手机的硬盘上,并使用树形结构来快速定位到需要的数据。当我们在查询数据时,需要根据数据所在的位置来查找,使用B树或B+树可以让查找更加高效。

MySQL是一种关系型数据库管理系统,它通过从磁盘读取数据到内存来提高数据访问效率。MySQL以磁盘块为基本单位,在同一磁盘块中的数据会被一次性读取出来,不是按需读取。对于InnoDB存储引擎,它使用页作为数据读取单位,页是其磁盘管理的最小单位,默认大小是16kb。一行数据的大小是1kb,一个页可以存放16行这样的数据。当查找某个页里面的数据时,需要首先找到它所在的页。

在查询数据时,一个页中的每条数据都能定位数据记录的位置,这会减少磁盘I/O的次数,提高查询效率。InnoDB存储引擎在设计时将根节点常驻内存,以达到树的深度不超过3的目的,也就是说I/O不超过3次。

树形结构的数据可以让系统高效地找到数据所在的磁盘块。其中B树和B+树是两种常见的索引结构。B树的结构是每个节点中有key和value,而每一个页的存储空间是16kb,如果数据较大时将会导致一页能存储数据量的数量很小。B+Tree的结构是将所有数据记录节点按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度。

B+树索引具有高扇出性,因此在数据库中,B+树的高度一般都在2-4层,这也就是说查找某一键值的行记录时最多只需要2到4次I/O。聚集索引和辅助索引是B+树索引的两种类型。

一般的机械磁盘每秒至少可以做100次IO, 2~4次的IO意味着查询时间只需0.02~0.04秒。

假设每条sql信息为1kb,主键ID为bigint型,一颗高度为2,3,4高度的B+树分别可以存储多少行数据?

我们可以把 B+树的结构想象成一个大树,每个节点都分叉成多个小枝丫,而每个小枝丫的末端都是数据记录。如果我们用一个数字来表示每个数据记录,那么这个数字就是每条 sql 信息的主键 ID,而整个 B+树就是用来帮助我们快速定位这些记录的。

首先,B+树是一种树状结构,它的高度影响着它能够存储多少数据。我们假设数据记录的主键 ID 是 bigint 类型,那么它占用 8 个字节的空间。而每个节点除了存储数据记录的信息外,还需要存储指向下一个节点的指针,这个指针占用 6 个字节的空间。

然后我们来计算一下一颗高度为 2、3、4 的 B+树能够存储多少行数据。我们先假设每个数据记录的信息占用 1KB,也就是 1024 字节。

对于高度为 2 的 B+树,它的根节点指向的子节点是叶子节点,而这些叶子节点则存储着实际的数据记录。每个节点最多存储 1170 个指向下一个节点的指针,而每个节点的大小是 16KB,因此一个节点最多可以存储 1170 行数据,也就是 1170 个主键 ID。而高度为 2 的 B+树一共有两层,因此它最多可以存储的数据行数就是 1170 * 1170 = 1,368,900 行。

对于高度为 3 的 B+树,它的根节点指向的子节点是非叶子节点,而这些非叶子节点(除了叶子节点外的所有节点)存储着指向下一层子节点的指针。每个非叶子节点可以存储 1170 个指针和键值,因此一个非叶子节点最多可以指向 1170 个叶子节点。而每个叶子节点最多可以存储 1170 行数据,因此一个非叶子节点最多可以存储 1170 * 1170 行数据。高度为 3 的 B+树一共有三层,因此它最多可以存储的数据行数就是 1170 * 1170 * 1170 = 17,576,490 行。

对于高度为 4 的 B+树,同理,它的根节点指向的子节点还是非叶子节点,而每个非叶子节点最多可以指向 1170 个子节点。由于高度为 4,因此一共会有四层,而每个叶子节点最多可以存储 1170 行数据。因此,一个非叶子节点最多可以存储 1170 * 1170 * 1170 行数据。高度为 4 的 B+树最多可以存储的数据行数就是 1170 * 1170 * 1170 * 1170 = 20,348,847,000 行。也就是说,它可以存储 200亿行左右的数据。

这就是 B+树的强大之处,它可以快速地定位到数据记录,而且支持快速的插入和删除操作。因此,在数据库中,B+树被广泛地应用于索引的建立和优化。

为什么选用B+树做索引而不选用二叉树或者B树?

你是否有过这样的经历:打开电脑,想看看自己的照片或者文档,可是不知道在哪个文件夹里面?于是你开始在各个文件夹之间不停地点击,直到找到了目标文件。这个过程其实就像在磁盘里面寻找数据,而数据库索引就是帮助我们快速定位数据所在位置的工具。

在数据库中,我们需要通过一些属性值来查找数据,比如查找某个人的名字、年龄或地址等信息。如果数据量很小,我们可以通过一些简单的方法来完成查找,比如使用二叉查找树。但是如果数据量很大,这种方法就会变得非常缓慢。因为,每次查找都需要从根节点开始,一级一级地向下搜索,直到找到目标数据为止,这个过程需要不停地访问磁盘,增加了IO操作的次数,导致查询效率非常低下。

为了解决这个问题,我们发明了B树和B+树。它们经过了一些特别的设计和改进,能够更好地适应磁盘存储的特点,使得数据库索引的查询速度更快。

当我们要在数据库中进行索引查询的时候,我们需要快速地定位到所需数据所对应的位置,这个过程涉及到的数据量非常大,因此我们需要一种高效的数据结构来实现索引查询。在这种情况下,B+树成了一个非常好的选择。B+树在数据库索引中应用非常广泛,因为它有以下几个优点:

1.减少IO次数

在数据库中,索引是存储在磁盘上的。当数据量非常大时,我们不能把整个索引全部加载到内存中,只能逐一加载每一个磁盘页(对应索引树的节点)。因此,我们需要减少IO次数。而树的高度影响IO次数,B+树相对于其他树结构,如二叉树和B树,更“矮胖”,树的高度较小,可以快速定位到所需数据所在的节点,从而减少IO次数。

举个例子来说,如果我们要在整个数据库中查找一个学生的学号,如果使用二叉树,树的高度将会非常高,需要进行多次IO操作才能找到该学号对应的节点。而使用B+树,查找速度更快,只需要定位到所需数据所在节点即可,也就是说,IO操作次数更少。

2.稳定查询

在查找过程中,我们希望查询效率高且稳定,不希望有过多的波动。而B+树对于范围查找来说,仅需要遍历叶子节点链表即可,不需要排序操作,因为叶子节点已经对索引进行了排序操作。而B树则需要重复地中序遍历,找到所有的范围内的节点。因此,B+树的查询效率更高,而且更加稳定。

3.存储效率高

B+树的中间节点不保存数据,只保存索引信息,这样磁盘页能容纳更多节点元素,更“矮胖”。而B树无论是叶子节点还是非叶子节点,都会保存数据,这就导致在非叶子节点中能保存的指针数量变少,指针少的情况下要保存大量数据,只能增加树的高度,导致IO操作变多,查询性能变低。

举个例子来说,如果我们要在数据库中查找所有姓张的学生,如果使用B树,由于每个节点都保存了数据,那么在非叶子节点中要保存大量数据时,就只能增加树的高度,导致IO次数急剧增加,查询效率变低。而使用B+树,由于中间节点不保存数据,可以容纳更多节点元素,树高度较小,可以快速定位到所需数据所在节点,从而减少IO次数。

因此,虽然二叉树和B树在理论上的查找速度和比较次数最小,但是在实际的数据库索引应用中,B+树成为了最佳选择,因为它具有高效率、稳定性、存储效率高等优点。

为什么用 B+ 树做索引而不用哈希表做索引?

首先,我们需要了解一下索引的作用。索引是数据库中用于加速查询的数据结构。在进行查询时,数据库可以通过索引快速定位到需要查询的数据,避免了全表扫描的高开销。

哈希表和 B+ 树都是常用的索引结构。哈希表是将索引字段通过哈希映射成对应的哈希码,然后再存放在对应的位置。B+ 树则是一种树状结构,根据索引字段构建出一颗多层次的树,通过不断的分支和定位,最终找到对应数据所在的位置。

那么,为什么我们更倾向于使用 B+树做索引呢?原来,哈希表存在以下几个问题:

第一,模糊查找不支持。如果我们想要查找名字中包含“小明”的所有人,哈希表无法实现。因为哈希表只能根据精确的哈希码定位到一个位置,而无法处理模糊性查找。

第二,范围查找不支持。如果我们要查找 ID 在 100 到 400 之间的人,哈希表也无能为力。因为哈希表只能处理等值查找,无法处理范围查找。

第三,哈希冲突问题。当多个索引字段映射成相同的哈希码时,就会产生哈希冲突。这时,哈希表会将这些索引字段存储在同一个位置上,形成一条长链表。这会导致查找效率下降,因为我们需要遍历整个链表才能找到对应的数据。

而 B+ 树则能够通过最左前缀原则快速找到对应的数据。同时,B+ 树的叶子节点是按顺序存储的,所以支持范围查找。B+ 树还可以设置分支节点和叶子节点的大小,可以控制每个节点所存储的数据量,从而优化查询性能。

综上所述,虽然哈希表也是一种高效的数据结构,但在构建索引时,B+树更加灵活和可靠,能够应对更多的查询场景,因此更受欢迎。


🔔如果您需要转载或者搬运这篇文章的话,非常欢迎您私信我哦~

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
5月前
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
5月前
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
179 4
|
7月前
|
存储 关系型数据库 MySQL
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
|
9月前
|
关系型数据库 MySQL 数据库
Mysql的索引
MYSQL索引主要有 : 单列索引 , 组合索引和空间索引 , 用的比较多的就是单列索引和组合索引 , 空间索引我这边没有用到过 单列索引 : 在MYSQL数据库表的某一列上面创建的索引叫单列索引 , 单列索引又分为 ● 普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。 ● 唯一索引:索引列中的值必须是唯一的,但是允许为空值 ● 主键索引:是一种特殊的唯一索引,不允许有空值 ● 全文索引: 只有在MyISAM引擎、InnoDB(5.6以后)上才能使⽤用,而且只能在CHAR,VARCHAR,TEXT类型字段上使⽤用全⽂文索引。
|
5月前
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
134 2
|
12月前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
2414 10
|
6月前
|
存储 关系型数据库 MySQL
MySQL覆盖索引解释
总之,覆盖索引就像是图书馆中那些使得搜索变得极为迅速和简单的工具,一旦正确使用,就会让你的数据库查询飞快而轻便。让数据检索就像是读者在图书目录中以最快速度找到所需信息一样简便。这样的效率和速度,让覆盖索引成为数据库优化师傅们手中的尚方宝剑,既能够提升性能,又能够保持系统的整洁高效。
167 9
|
7月前
|
机器学习/深度学习 关系型数据库 MySQL
对比MySQL全文索引与常规索引的互异性
现在,你或许明白了这两种索引的差异,但任何技术决策都不应仅仅基于理论之上。你可以创建你的数据库实验环境,尝试不同类型的索引,看看它们如何影响性能,感受它们真实的力量。只有这样,你才能熟悉它们,掌握什么时候使用全文索引,什么时候使用常规索引,以适应复杂多变的业务需求。
183 12
|
11月前
|
存储 关系型数据库 MySQL
MySQL索引学习笔记
本文深入探讨了MySQL数据库中慢查询分析的关键概念和技术手段。
703 81
|
8月前
|
SQL 存储 关系型数据库
MySQL选错索引了怎么办?
本文探讨了MySQL中因索引选择不当导致查询性能下降的问题。通过创建包含10万行数据的表并插入数据,分析了一条简单SQL语句在不同场景下的执行情况。实验表明,当数据频繁更新时,MySQL可能因统计信息不准确而选错索引,导致全表扫描。文章深入解析了优化器判断扫描行数的机制,指出基数统计误差是主要原因,并提供了通过`analyze table`重新统计索引信息的解决方法。
210 3

推荐镜像

更多