当前位置: 首页 > news >正文

MySQL 进阶专题:索引(索引原理/操作/优缺点/B+树)

在数据库的秋招面试中,索引(Index)是一个经典且高频的题目。索引的作用类似于书中的目录📖,它能够显著加快数据库查询的速度。本文将深入探讨索引的概念、作用、优缺点以及背后的数据结构,帮助你从原理到应用全面掌握这一重要知识点。


什么是索引?🤔

在数据库中,索引是一种特殊的数据结构,用于加快查询操作的速度。当我们执行 SELECT 查询时,数据库默认会通过逐行扫描的方式来完成查询。例如,当我们使用 WHERE 语句进行条件查询时,数据库会依次读取数据表的每一行,并将其带入条件中进行判断。这种遍历操作的时间复杂度是 O(N),其中 N 是表中的总行数。

然而,这种遍历操作有一个显著的问题:每次读取一行数据都需要访问硬盘💾。硬盘 I/O 的速度远低于内存操作,尽管时间复杂度是 O(N),实际执行效率却受到硬盘性能的极大限制。因此,索引通过创建一个有序的数据结构(如 B+ 树)充当数据的目录,使得数据库可以快速定位满足条件的数据,避免对表数据的全表扫描,从而显著提升查询速度🚀。


索引的优缺点 ⚖️

优点 ✅

  1. 加快查询速度:索引的最大优势在于它可以显著提高查询效率,尤其是在处理大数据量的场景下。通过索引,数据库可以快速定位到目标数据行,避免无效扫描。

  2. 适用于高频查询场景:在许多实际业务中,查询操作的频率远远高于数据的增删改操作。引入索引后,整体性能会得到显著提升。

  3. 支持复杂查询:索引不仅适用于简单的等值查询,还能提高范围查询(如 ><)、模糊匹配(如 LIKE)以及多表连接的效率。

缺点 ❌

  1. 占用额外存储空间:索引本质上是一种额外的数据结构,需要占用存储空间。对于嵌入式设备或存储资源有限的环境,过多的索引可能会成为瓶颈。

  2. 影响增删改效率:在插入、删除和更新操作时,索引也需要同步更新,这会额外增加 I/O 操作。例如,执行以下 SQL:

    DELETE FROM student WHERE id = 5;
    

    数据库需要先通过索引定位到目标数据行,然后更新索引结构。

  3. 需要精心设计:不合理的索引设计可能导致查询性能没有显著提升,甚至适得其反。因此,在实际应用中,需要根据具体业务场景对索引进行规划和调整。


操作索引的 SQL 语句 🛠️

在数据库中,我们可以通过以下 SQL 语句来操作索引:

1. 查看索引 👀

SHOW INDEX FROM table_name;

这条语句用于查看某个表的索引信息。通过它,我们可以了解表中已经创建了哪些索引,以及每个索引的具体属性。

2. 创建索引 🏗️

CREATE INDEX index_name ON table_name(column_name);

创建索引是一个需要谨慎操作的过程。对于小表来说,创建索引的影响较小;但对于大表来说,创建索引可能会触发大量的硬盘 I/O 操作,导致系统性能短暂下降。因此,在设计数据库时,应该提前规划需要创建的索引,尽量避免在线上环境对大表直接创建索引。

3. 删除索引 🗑️

DROP INDEX index_name ON table_name;

删除索引的操作相对简单,但需要注意的是,删除索引后,相关查询的性能可能会显著下降。删除索引的操作同样会对数据库资源造成一定的消耗。


索引背后的数据结构 🧩

索引的实现依赖于特定的数据结构。常见的索引数据结构包括二叉搜索树、哈希表和 B+ 树。然而,二叉搜索树和哈希表并不适合用于数据库索引。

为什么二叉搜索树和哈希表不适合?🛑

  1. 二叉搜索树:当数据量较大时,二叉搜索树的高度会显著增加,导致查询需要多次比较。每次比较都伴随着硬盘 I/O 操作,这会显著降低查询效率。

  2. 哈希表:哈希表虽然能够快速完成等值查询,但它不支持范围查询(如 ><)以及模糊查询(如 LIKE)。此外,哈希表对多列的联合查询支持较弱,因此不适合作为数据库索引的基础数据结构。

B+ 树:数据库索引的理想选择 🌟

B+ 树是 B 树的一种改进数据结构,非常适合用于实现数据库索引。其主要特点包括:

  1. 降低树的高度,减少 I/O 操作:B+ 树是 N 叉树,每个节点可以存储多个键值,大大降低了树的高度。相比二叉树,B+ 树的查询路径更短,每次查询需要的 I/O 次数更少。

  2. 叶子节点构成全集,支持范围查询:B+ 树的叶子节点通过链表相连,构成数据的全集。这种结构使得范围查询非常高效,尤其适用于连续区间的数据检索。

  3. 查询性能稳定:在 B+ 树中,所有查询最终都会落到叶子节点。因此,无论查询的目标数据在哪里,查询的性能始终保持稳定。

  4. 非叶子节点存储索引键值:B+ 树的非叶子节点只存储索引的键值,而不存储实际的数据行。这种设计显著降低了非叶子节点的存储空间消耗,从而进一步减少了硬盘 I/O 操作。


B+ 树示意图 🌳

以下是一棵典型的 B+ 树的结构示意图,用于帮助理解其结构和特点:

            [8 | 15]/       \[2 | 5 | 8]  [11  | 13  |  15]/  |    \     /    |    \     \[1] [3|4] [6|7] [10] [12]  [13] [14 | 15]

特点分析:

  1. 非叶子节点:仅存储索引键值(如 8, 15 等),用来引导查询路径。
  2. 叶子节点:存储所有实际数据,并通过链表连接,形成完整的有序数据集。
  3. 范围查询:例如,查找范围 4 <= key <= 10,只需要遍历从键 4 开始到键 10 结束的链表节点,无需逐个比较。

B+ 树的优化

通过 B+ 树的多叉结构,大幅降低树的高度,减少硬盘访问次数,显著优化数据库查询性能。


索引的实际应用场景 📋

  1. 高频查询表:如电商系统的商品表、用户表,通过索引显著提升基于主键或唯一键的查询性能。

  2. 排序和分组操作:索引能够优化 ORDER BYGROUP BY 的操作,减少排序所需的计算开销。

  3. 多表连接查询:索引支持高效的多表 JOIN 查询,在复杂查询场景下避免不必要的全表扫描。


总结 📝

索引是数据库优化的核心工具之一。通过合理设计和使用索引,可以显著提高查询效率,降低系统资源的使用成本。然而,索引的设计需要权衡查询和增删改操作的需求,结合具体业务场景做出合理的选择。

B+ 树是当前主流数据库中索引实现的核心数据结构,其高效的范围查询能力、稳定的查询性能以及较低的存储开销使其成为数据库索引的理想选择。希望本文的讲解能帮助你深入理解索引的原理,并在实际开发和面试中游刃有余。💪

相关文章:

MySQL 进阶专题:索引(索引原理/操作/优缺点/B+树)

在数据库的秋招面试中&#xff0c;索引&#xff08;Index&#xff09;是一个经典且高频的题目。索引的作用类似于书中的目录&#x1f4d6;&#xff0c;它能够显著加快数据库查询的速度。本文将深入探讨索引的概念、作用、优缺点以及背后的数据结构&#xff0c;帮助你从原理到应…...

用NeuralProphet预测股价:AI金融新利器(附源码)

作者&#xff1a;老余捞鱼 原创不易&#xff0c;转载请标明出处及原作者。 写在前面的话&#xff1a;我用NeuralProphet模型预测了股票价格&#xff0c;发现其通过结合时间序列分析和神经网络算法&#xff0c;确实能提供比传统Last Value方法更精准的预测。经过一系列超参数调优…...

【Elasticsearch】parent aggregation

在Elasticsearch中&#xff0c;Parent Aggregation是一种特殊的单桶聚合&#xff0c;用于选择具有指定类型的父文档&#xff0c;这些类型是通过一个join字段定义的。以下是关于Parent Aggregation的详细介绍&#xff1a; 1.基本概念 Parent Aggregation是一种聚合操作&#x…...

IDEA使用Auto-dev+DeepSeek 10分钟快速集成,让java开发起飞

在当今的软件开发领域,AI 工具的辅助作用愈发凸显,DeepSeek AI 便是其中的佼佼者。它凭借强大的自然语言处理能力和高效的代码生成能力,成为众多开发者的得力助手。而 IntelliJ IDEA 作为一款广受欢迎的集成开发环境(IDE),若能与 DeepSeek AI 无缝集成,无疑将为开发者带…...

ASP.NET Core中间件Markdown转换器

目录 需求 文本编码检测 Markdown→HTML 注意 实现 需求 Markdown是一种文本格式&#xff1b;不被浏览器支持&#xff1b;编写一个在服务器端把Markdown转换为HTML的中间件。我们开发的中间件是构建在ASP.NET Core内置的StaticFiles中间件之上&#xff0c;并且在它之前运…...

使用page assist浏览器插件结合deepseek-r1 7b本地模型

为本地部署的DeepSeek R1 7b模型安装Page Assist&#xff0c;可以按照以下步骤进行&#xff1a; 一、下载并安装Ollama‌ 首先&#xff0c;你需要下载并安装Ollama&#xff0c;这是部署DeepSeek所必需的工具。你可以访问Ollama的官方网站&#xff08;ollama.com&#xff09;下…...

【华为OD-E卷 - 108 最大矩阵和 100分(python、java、c++、js、c)】

【华为OD-E卷 - 最大矩阵和 100分&#xff08;python、java、c、js、c&#xff09;】 题目 给定一个二维整数矩阵&#xff0c;要在这个矩阵中选出一个子矩阵&#xff0c;使得这个子矩阵内所有的数字和尽量大&#xff0c;我们把这个子矩阵称为和最大子矩阵&#xff0c;子矩阵的…...

【Reading Notes】Favorite Articles from 2025

文章目录 1、January2、February3、March4、April5、May6、June7、July8、August9、September10、October11、November12、December 1、January 极越之后&#xff0c;中国车市只会倒下更多人&#xff08;2025年01月01日&#xff09; 在这波枪林弹雨中&#xff0c;合资品牌中最…...

云计算行业分析

云计算作为数字经济的核心基础设施&#xff0c;未来十年将持续重塑全球科技格局&#xff0c;并渗透到几乎所有行业的数字化转型中。 一、云计算的发展潜力 1. 技术融合驱动爆发式创新 AI与云计算的深度耦合 - **智能云服务**&#xff1a;云厂商将提供预训练模型、自动化ML工…...

【Linux系统】线程:线程的优点 / 缺点 / 超线程技术 / 异常 / 用途

1、线程的优点 创建和删除线程代价较小 创建一个新线程的代价要比创建一个新进程小得多&#xff0c;删除代价也小。这种说法主要基于以下几个方面&#xff1a; &#xff08;1&#xff09;资源共享 内存空间&#xff1a;每个进程都有自己独立的内存空间&#xff0c;包括代码段…...

3.攻防世界 weak_auth

题目描述提示 是一个登录界面&#xff0c;需要密码登录 进入题目页面如下 弱口令密码爆破 用1 or 1 #试试 提示用admin登录 则尝试 用户名admin密码&#xff1a;123456 直接得到flag 常用弱口令密码&#xff08;可复制&#xff09; 用户名 admin admin-- admin or -- admin…...

代码随想录算法训练营| 二叉树总结

代码随想录 二叉树的理论基础&#xff1a;二叉树种类、存储方式、遍历方式、定义方式 二叉树遍历&#xff1a;深度优先和广度优先 二叉树属性&#xff1a;对称、深度、节点、平衡、路径、回溯 修改与构造&#xff1a;反转、构造、合并 涉及到二叉树的构造&#xff0c;无论普…...

Python OCR工具pytesseract识别数字验证码

直接下载地址&#xff1a;https://digi.bib.uni-mannheim.de/tesseract/ 找的最新版本&#xff1a; 我添加了math 跟chinese&#xff08;因为是国内网络的原因吧&#xff0c;下载都失败&#xff0c;所以不用选择&#xff0c;后面自己下载后&#xff0c;添加到相应目录就好&…...

SpringBoot开发(五)SpringBoot接收请求参数

1. SpringBoot接收请求参数 1.1. 获取参数的方式 &#xff08;1&#xff09;通过request对象获取参数   &#xff08;2&#xff09;RequestParam(针对请求头方式为x-www-form-ur lencoded)   &#xff08;3&#xff09;RequestBody(针对请求头方式为application/json)   …...

文件基础IO

理解"文件" 1-1 狭义理解 文件在磁盘里磁盘是永久性存储介质&#xff0c;因此文件在磁盘上的存储是永久性的磁盘是外设&#xff08;即是输出设备也是输入设备&#xff09;磁盘上的文件 本质是对文件的所有操作&#xff0c;都是对外设的输入和输出简称IO 1-2 广义理…...

05vue3实战-----配置项目代码规范

05vue3实战-----配置项目代码规范 1.集成editorconfig配置2.使用prettier工具2.1安装prettier2.2配置.prettierrc文件&#xff1a;2.3创建.prettierignore忽略文件2.4VSCode需要安装prettier的插件2.5VSCod中的配置2.6测试prettier是否生效 3.使用ESLint检测3.1VSCode需要安装E…...

八大排序算法细讲

目录 排序 概念 运用 常见排序算法 插入排序 直接插入排序 思想&#xff1a; 步骤&#xff08;排升序&#xff09;: 代码部分&#xff1a; 时间复杂度&#xff1a; 希尔排序 思路 步骤 gap的取法 代码部分&#xff1a; 时间复杂度&#xff1a; 选择排序 直接选…...

网络爬虫学习:借助DeepSeek完善爬虫软件,增加停止任务功能

一、引言 我从24年11月份开始学习网络爬虫应用开发&#xff0c;经过2个来月的努力&#xff0c;终于完成了开发一款网络爬虫软件的学习目标。这几天对本次学习及应用开发进行一下回顾总结。前面已经发布了两篇日志&#xff1a; 网络爬虫学习&#xff1a;应用selenium从搜*狐搜…...

docker安装es及分词器ik

系统是macos&#xff0c;docker是docker-desktop 拉取镜像 docker pull bitnami/elasticsearch 启动docker镜像 docker create -e "discovery.typesingle-node" \ --name elasticsearch1 -p 9200:9200 -p 9300:9300 \ bitnami/elasticsearch:8.17.1 测试是否好…...

【论文阅读】On the Security of “VOSA“

On the Security of Verifiable and Oblivious Secure Aggregation for Privacy-Preserving Federated Learning -- 关于隐私保护联邦中可验证与遗忘的安全聚合的安全性 论文来源摘要Introduction回顾 VOSA 方案对VOSA不可伪造性的攻击对于类型 I 的攻击对于类型 II 的攻击 论文…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...