数据库检索

简介: 本文探讨如何用B+树为海量磁盘数据建立高效索引。由于磁盘访问远慢于内存,关键在于减少磁盘I/O次数。B+树通过多路平衡查找、节点大小匹配磁盘块、顺序访问优化等方式,显著提升磁盘数据检索效率,广泛应用于MySQL等数据库系统。

数据库检索:如何使用 B+ 树对海量磁盘数据建立索引?
在基础篇中,我们学习了许多和检索相关的数据结构和技术。但是在大规模的数据环境下,这些技术的应用往往会遇到一些问题,比如说,无法将数据全部加载进内存。再比如说,无法支持索引的高效实时更新。而且,对于复杂的系统和业务场景,我们往往需要对基础的检索技术进行组合和升级。这就需要我们对实际的业务问题和解决方案十分了解。

所以,从这一讲开始,我会和你一起探讨实际工作中的系统和业务问题,分享给你一些工业界中常见的解决方案,帮助你积累对应的行业经验,让你能够解决工作中的检索难题。

在工业界中,我们经常会遇到的一个问题,许多系统要处理的数据量非常庞大,数据无法全部存储在内存中,需要借助磁盘完成存储和检索。我们熟悉的关系型数据库,比如 MySQL 和 Oracle,就是这样的典型系统。

数据库中支持多种索引方式,比如,哈希索引、全文索引和 B+ 树索引,其中 B+ 树索引是使用最频繁的类型。因此,今天我们就一起来聊一聊磁盘上的数据检索有什么特点,以及为什么 B+ 树能对磁盘上的大规模数据进行高效索引。

磁盘和内存中数据的读写效率有什么不同?

首先,我们来探讨一下,存储在内存中和磁盘中的数据,在检索效率方面有什么不同。

内存是半导体元件。对于内存而言,只要给出了内存地址,我们就可以直接访问该地址取出数据。这个过程具有高效的随机访问特性,因此内存也叫 随机访问存储器(Random Access Memory,即 RAM)。内存的访问速度很快,但是价格相对较昂贵,因此一般的计算机内存空间都相对较小。

而磁盘是机械器件。磁盘访问数据时,需要等磁盘盘片旋转到磁头下,才能读取相应的数据。尽管磁盘的旋转速度很快,但是和内存的随机访问相比,性能差距非常大。到底有多大呢?一般来说,如果是随机读写,会有 10 万到 100 万倍左右的差距。但如果是顺序访问大批量数据的话,磁盘的性能和内存就是一个数量级的。为什么会这样呢?这和磁盘的读写原理有关。那具体是怎么回事呢?

磁盘的 最小读写单位是扇区,较早期的磁盘一个扇区是 512 字节。随着磁盘技术的发展,目前常见的磁盘扇区是 4K 个字节。操作系统一次会读写多个扇区,所以操作系统的最小读写单位是 块(Block),也叫作 簇(Cluster)。当我们要从磁盘中读取一个数据时,操作系统会一次性将整个块都读出来。因此,对于大批量的顺序读写来说,磁盘的效率会比随机读写高许多。

现在你已经了解磁盘的特点了,那我们就可以来看一下,如果使用之前学过的检索技术来检索磁盘中的数据,检索效率会是怎样的呢?

假设有一个有序数组存储在硬盘中,如果它足够大,那么它会存储在多个块中。当我们要对这个数组使用二分查找时,需要先找到中间元素所在的块,将这个块从磁盘中读到内存里,然后在内存中进行二分查找。如果下一步要读的元素在其他块中,则需要再将相应块从磁盘中读入内存。直到查询结束,这个过程可能会多次访问磁盘。我们可以看到,这样的检索性能非常低。

由于磁盘相对于内存而言访问速度实在太慢,因此,对于磁盘上数据的高效检索,我们有一个极其重要的原则:对磁盘的访问次数要尽可能的少!

那问题来了,我们应该如何减少磁盘的访问次数呢?将索引和数据分离 就是一种常见的设计思路。

如何将索引和数据分离?

我们以查询用户信息为例。我们知道,一个系统中的用户信息非常多,除了有唯一标识的 ID 以外,还有名字、邮箱、手机、兴趣爱好以及文章列表等各种信息。一个保存了所有用户信息的数组往往非常大,无法全部放在内存中,因此我们会将它存储在磁盘中。
一个数组元素datadataID3ID2ID1ID4datadata一个用户信息(数据量大)

相关文章
|
1天前
|
存储 负载均衡 搜索推荐
大规模检索系统
本讲介绍大规模检索系统如何通过分布式技术加速检索。通过索引拆分,将倒排索引分散到多台服务器内存中,减少单机数据规模和磁盘访问,从而提升单次查询效率。结合分发服务器与负载均衡,实现高吞吐、低延迟的分布式检索架构。
|
17天前
|
缓存 运维 监控
一次内存诊断,让资源利用率提升 40%:揭秘隐式内存治理
阿里云云监控 2.0 推出 SysOM 底层操作系统诊断能力,基于 eBPF + BTF 协同分析,无需侵入业务,即可一键完成从物理页到文件路径、再到容器进程的全栈内存归因,让“黑盒内存”无所遁形。
420 68
|
1天前
|
搜索推荐 算法 UED
15 | 最近邻检索(上):如何用局部敏感哈希快速过滤相似文章?
在搜索引擎与推荐系统中,相似文章去重至关重要。本文介绍如何利用向量空间模型将文章转化为高维向量,并通过局部敏感哈希(如SimHash)实现高效近似最近邻检索,结合抽屉原理优化索引,快速找出内容相似的文章,提升用户体验。该技术广泛应用于网页去重、图像识别等场景。
|
1天前
|
存储 开发工具 git
05-Gitlab容器环境搭建
本文介绍如何通过Docker搭建Gitlab CE(社区版)环境。包含拉取镜像、创建持久化目录、运行容器并映射配置、数据和日志卷,以及访问Gitlab并初始化项目的方法。详细说明了SSH与HTTP访问配置、初始密码获取,并提供本地代码上传的两种方式,帮助快速部署并使用私有代码仓库。
|
1天前
|
程序员 API
7、Lambda表达式
Lambda表达式又称匿名函数,语法为(参数)->表达式,本质是函数对象,用于行为参数化,如Stream API、QueryWrapper等场景。相比匿名内部类,Lambda更简洁,需配合函数式接口使用,且在运行时动态生成类,其this指向也与匿名内部类不同。
|
1天前
|
NoSQL 中间件 关系型数据库
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:如何进行Docker部署后端
GoWind Admin风行是一款企业级中后台框架,支持Docker一键部署。通过Makefile封装构建流程,提供docker-compose全量部署与docker run单服务部署两种模式,适配开发、生产多场景。支持服务增减灵活配置,助力高效容器化落地。
31 1
|
1天前
|
NoSQL 索引
SSTable 的分层管理设计
SSTable分层管理通过将文件按层级组织,逐层合并,控制每层容量上限,减少多路归并规模,避免全量重叠,提升查询效率与系统性能,是LevelDB高效读写的核心设计。
|
1天前
|
存储 自然语言处理 分布式计算
索引构建
搜索引擎如何为万亿网页构建索引?通过分治与多路归并,将文档拆分为小集合,在内存中生成倒排索引后写入磁盘,再合并多个有序临时文件,最终生成全局倒排文件。词典可加载至内存或用B+树管理,实现高效检索。该过程类似MapReduce,支持分布式扩展。
|
1天前
|
存储 算法 搜索推荐
数组的检索效率
二分查找通过将有序数组不断折半,每次比较中间值与目标值,缩小搜索范围至一半,实现O(log n)高效检索,显著优于遍历的O(n),适用于大规模有序数据查询。
|
1天前
|
Java Maven Spring
动态代理:面向接口编程,屏蔽 RPC 处理流程
本节讲解动态代理在RPC中的核心作用:通过面向接口编程,利用JDK动态代理技术生成代理类,拦截接口调用并透明嵌入远程通信逻辑,屏蔽底层网络细节,实现“本地调用即远程调用”的无缝体验,提升开发效率与系统解耦能力。