MySQL的查找加速器——索引

文章目录

目录

前言

一、基础概念:什么是 MySQL 索引?

二、底层数据结构:为什么 InnoDB 偏爱 B + 树?

B + 树的结构特点(以短链接表short_link的short_code索引为例):

B + 树的优势:

三、索引类型:按功能和结构划分

1. 按功能划分(常用类型)

2. 按物理存储划分(InnoDB 核心区别)

四、工作原理:索引如何加速查询?

场景 1:通过short_code查询长链接(SELECT long_url FROM short_link WHERE short_code = 'abc123')

场景 2:查询 “用户 123 创建的所有短链”(SELECT * FROM short_link WHERE user_id = 123 ORDER BY create_time)

五、优缺点:索引不是 “银弹”

优点:

缺点:

六、最佳实践:如何正确使用索引?

1. 适合建索引的场景

2. 不适合建索引的场景

3. 避免索引失效的常见坑

总结


前言

        MySQL 索引是数据库性能优化的核心工具,如同书籍的目录,能帮助数据库快速定位数据,避免全表扫描。下面从基础概念、底层结构、类型划分、工作原理、优缺点及最佳实践六个维度详细解析,并结合实际业务场景(如短链接平台、电商系统)说明其应用


一、基础概念:什么是 MySQL 索引?

索引是 MySQL 在存储引擎层(如 InnoDB)创建的数据结构,通过对表中特定字段的值进行排序和组织,实现 “快速定位数据位置” 的功能。

  • 核心目标:减少磁盘 I/O 次数(数据库操作中最耗时的环节),提升查询效率。
  • 类比:查询表中short_code = 'abc123'的短链接时,无索引需逐行扫描全表;有索引时,可直接通过索引定位到该记录的物理地址,类似查字典时通过拼音目录找汉字。

二、底层数据结构:为什么 InnoDB 偏爱 B + 树?

MySQL 索引的底层数据结构取决于存储引擎,InnoDB(MySQL 默认引擎)的索引基于B + 树实现,而非哈希表、二叉树等,原因是 B + 树更适合数据库的读写场景。

B + 树的结构特点(以短链接表short_linkshort_code索引为例):
  • 层级化结构:由根节点、非叶子节点、叶子节点组成,层级通常为 3-4 层(百万级数据仅需 3 次 I/O)。
  • 叶子节点存完整数据(聚簇索引)或主键(非聚簇索引)
    • 叶子节点按short_code值有序排列,且通过双向链表连接,支持范围查询(如short_code > 'abc' AND short_code < 'def')。
    • 非叶子节点仅存 “索引值 + 子节点指针”,不存实际数据,节省内存空间。
B + 树的优势:
  1. 平衡性:左右子树高度差不超过 1,保证查询效率稳定(不会出现极端情况下的长路径)。
  2. 范围查询高效:叶子节点的双向链表可快速遍历连续数据(如查询 “创建时间在 2023-01-01 到 2023-01-31 的短链接”)。
  3. 适配磁盘读写:节点大小通常为 16KB(InnoDB 页大小),单次 I/O 可加载整个节点,减少 I/O 次数。

三、索引类型:按功能和结构划分

1. 按功能划分(常用类型)
索引类型定义与特点适用场景(结合业务)
主键索引(PRIMARY KEY)表中唯一标识记录的索引,默认自动创建,字段值非空且唯一,InnoDB 中为主键聚簇索引。短链接表short_linkid字段(自增主键),或short_code(唯一短链码),用于唯一定位单条记录。
唯一索引(UNIQUE)字段值唯一(允许 NULL,但最多一个 NULL),可避免重复数据。短链接表的short_code字段(若不为主键),防止生成重复短链;用户表userphone字段,确保手机号唯一。
普通索引(INDEX)无唯一性约束,最常用的索引类型,仅用于加速查询。短链接表的user_id(查询 “某用户创建的所有短链”)、create_time(按时间筛选短链)。
联合索引(复合索引)对多个字段组合创建的索引,需遵循 “最左前缀原则”(查询条件需包含最左字段)。电商订单表order(user_id, create_time)联合索引,优化 “查询用户 A 在 2023 年的所有订单”。
全文索引(FULLTEXT)用于长文本字段(如varchartext)的关键词检索,支持自然语言查询。商品表productdescription字段,实现 “搜索含‘红酒’关键词的商品”。
2. 按物理存储划分(InnoDB 核心区别)
  • 聚簇索引(Clustered Index)
    索引与数据存储在一起,叶子节点直接存储完整的行数据(仅 InnoDB 有)。

    • 默认以主键为聚簇索引;若表无主键,InnoDB 会用唯一索引代替;若均无,则生成隐藏的row_id作为聚簇索引。
    • 例:短链接表short_link的主键id为聚簇索引,叶子节点存id, short_code, long_url, user_id等完整字段。
  • 非聚簇索引(Secondary Index)
    索引与数据分离,叶子节点仅存储 “索引值 + 聚簇索引值(主键)”,查询时需先查非聚簇索引得到主键,再通过聚簇索引查完整数据(称为 “回表”)。

    • 例:短链接表的user_id普通索引,叶子节点存user_id + id,查询user_id=123的短链详情时,需先通过user_id索引找到id,再用id查聚簇索引获取完整数据。

四、工作原理:索引如何加速查询?

以短链接平台的两个核心查询为例,解析索引的工作流程:

场景 1:通过short_code查询长链接(SELECT long_url FROM short_link WHERE short_code = 'abc123'
  1. short_code有唯一索引(非聚簇索引):

    • 数据库通过 B + 树查找short_code = 'abc123'的叶子节点,获取对应的主键id = 1001
    • 再通过聚簇索引(主键id)查找id = 1001的叶子节点,获取long_url(回表操作)。
  2. 若查询字段仅为short_codeidSELECT id, short_code FROM ...):

    • 非聚簇索引的叶子节点已包含short_code + id,无需回表,直接返回结果(称为 “覆盖索引”,性能更优)。
场景 2:查询 “用户 123 创建的所有短链”(SELECT * FROM short_link WHERE user_id = 123 ORDER BY create_time
  • user_id有普通索引,create_time有普通索引:

    • 先通过user_id索引筛选出所有user_id=123的记录,得到对应的id列表。
    • 再通过聚簇索引获取每条记录的完整数据,最后按create_time排序(需额外排序操作)。
  • 若建立(user_id, create_time)联合索引:

    • 索引叶子节点按user_id排序,同user_id内按create_time排序,筛选后可直接按顺序返回,无需额外排序(利用索引的有序性)。

五、优缺点:索引不是 “银弹”

优点:
  1. 加速查询:大幅减少扫描行数,百万级表中查询耗时可从秒级降至毫秒级。
  2. 优化排序 / 分组:利用索引的有序性,避免ORDER BY/GROUP BY时的文件排序(最耗时的操作之一)。
缺点:
  1. 占用存储空间:索引需单独存储,一张表若有 5 个索引,存储空间可能比表数据本身还大。
  2. 降低写入效率:新增 / 修改 / 删除数据时,需同步更新索引(B + 树的插入 / 平衡操作耗时),写入性能可能下降 50% 以上。

六、最佳实践:如何正确使用索引?

1. 适合建索引的场景
  • 频繁查询的字段:如短链接表的short_code(每次跳转都查询)、用户表的username(登录查询)。
  • 排序 / 分组字段:如订单表的create_time(按时间统计订单)、商品表的price(按价格排序)。
  • 联合查询条件:如WHERE a = ? AND b = ?,建立(a, b)联合索引比单字段索引更高效。
2. 不适合建索引的场景
  • 低频查询的字段:如 “用户最后登录 IP”(半年查一次),建索引浪费空间。
  • 字段值重复率高:如 “性别”(仅男 / 女),索引筛选效率低(几乎扫描全表)。
  • 大字段:如text类型的 “商品详情”,索引维护成本极高(字段越长,B + 树节点存储的索引值越少,层级越深)。
3. 避免索引失效的常见坑
  • 函数 / 表达式操作索引字段WHERE SUBSTR(short_code, 1, 3) = 'abc'会导致short_code索引失效(索引存原始值,函数处理后无法匹配)。
  • 类型转换WHERE short_code = 123short_code是字符串)会触发隐式转换,索引失效(需写成WHERE short_code = '123')。
  • 模糊查询左匹配WHERE short_code LIKE '%abc'(左模糊)索引失效,LIKE 'abc%'(右模糊)可命中索引。
  • 违反最左前缀原则(a, b, c)联合索引,仅WHERE b = ? AND c = ?无法命中索引(需包含最左字段a)。

总结

        MySQL 索引是 “以空间换时间” 的典型设计,核心价值是通过 B + 树等数据结构加速查询,但需根据业务场景合理设计(如短链接的short_code唯一索引、订单表的联合索引),避免滥用导致写入性能下降。理解索引的底层原理和失效场景,是数据库性能优化的关键。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/97926.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/97926.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Vue2手录11】Vue脚手架(@vue_cli)详解(环境搭建+项目开发示例)

一、前言&#xff1a;为什么需要 Vue 脚手架&#xff1f; 手动搭建 Vue 项目存在诸多痛点&#xff08;原笔记提及&#xff09;&#xff1a; 依赖管理复杂&#xff1a;需手动下载 Vue、Babel、Webpack 等工具&#xff0c;处理版本兼容性。配置繁琐&#xff1a;Webpack 配置、E…

自签发、CA机构签发、SSH、SCP、RSYNC,SUDO详解

一、为什么&#xff1f; 1. 自建CA为什么比Lets Encrypt强&#xff1f; 不能把CA放公网&#xff01;Lets Encrypt是给公网服务用的&#xff08;比如10.0.0.30的Web服务&#xff09;&#xff0c;但内网服务&#xff08;比如OpenVPN&#xff09;必须用自签CA。 CA私钥必须物理隔…

【Python】Python解决阿里云DataWorks导出数据1万条限制的问题

【Python】Python解决阿里云DataWorks导出数据1万条限制的问题一、前言二、脚本功能概述三、核心代码解析**1. 环境配置与安全设置****2. 用户配置区****3. 数据清洗函数****4. 核心逻辑**四、完整代码演示五、总结一、前言 在日常数据分析工作中&#xff0c;团队经常需要从阿…

计算机网络(一)基础概念

本篇文章为计算机网络相关知识点整理及扩展 基于B站计算机网络课程&#xff1a;https://www.bilibili.com/video/BV1p69tYZEvN/?spm_id_from333.1007.top_right_bar_window_history.content.click 如有错误&#xff0c;还望大家不吝指正 URL&#xff08;统一资源定位符&…

Git的工作区域和文件结构

Git的工作区域和文件结构 1. Git的工作区域2. Git的文件结构 打开.git文件&#xff0c;.git的文件结构如下&#xff1a; objects 存放已经提交的文件&#xff0c;也就是使用 git commit 进行操作后的文件。 index 存放已暂存的文件&#xff0c;也就是使用了 git add 进行操作后…

前端开发易错易忽略的 HTML 的 lang 属性

前言本文主要记录&#xff1a;前端开发中&#xff0c;一个本人错了好几年&#xff0c;看似无关紧要的小错误&#xff1a;HTML 的 lang 属性设置。正文HTML 的 lang 属性在HTML中&#xff0c;lang属性用于指定文档的语言。这对于搜索引擎优化&#xff08;SEO&#xff09;、屏幕阅…

【GD32】 GPIO 超详细总结 (江科大风格课件版)

GD32 GPIO 超详细总结 (江科大风格课件版)第一部分&#xff1a;GPIO 是什么&#xff1f; 名称&#xff1a;GPIO General Purpose Input/Output (通用输入输出口)作用&#xff1a;MCU与外部世界交互的桥梁。通过程序控制引脚输出高、低电平&#xff0c;或者读取引脚的电平状态。…

《嵌入式硬件(八):基于IMX6ULL的点灯操作》

一、IMX6ULL启动代码.global _start_start:ldr pc, _reset_handlerldr pc, _undefine_handlerldr pc, _svc_handlerldr pc, _prefetch_abort_handlerldr pc, _data_abort_handlerldr pc, _reserved_handlerldr pc, _irq_handlerldr pc, _fiq_handler_undefine_handler:ldr pc, …

Spring Boot 调度任务在分布式环境下的坑:任务重复执行与一致性保证

前言在实际业务开发中&#xff0c;调度任务&#xff08;Scheduled Task&#xff09; 扮演着重要角色&#xff0c;例如&#xff1a;定时同步第三方数据&#xff1b;定时清理过期缓存或日志&#xff1b;定时发送消息或报告。Spring Boot 提供了非常方便的 Scheduled 注解&#xf…

剖析ReAct:当大模型学会“边想边做”,智能体的进化之路

你是否曾惊叹于大语言模型&#xff08;LLM&#xff09;强大的推理能力&#xff0c;却又对其“纸上谈兵”、无法真正与世界交互而感到遗憾&#xff1f;你是否好奇&#xff0c;如何让AI不仅能“说”&#xff0c;更能“做”&#xff0c;并且在做的过程中不断思考和调整&#xff1f…

小型无人机传感器仿真模型MATLAB实现方案

一、系统架构设计 无人机传感器仿真模型需集成多物理场建模与数据融合模块&#xff0c;典型架构包含&#xff1a; 动力学模型&#xff1a;六自由度刚体运动方程传感器模型&#xff1a;IMU/GNSS/视觉/气压计数学建模数据融合层&#xff1a;卡尔曼滤波/EKF算法实现环境交互模块&a…

hadoop集群

ssh-keygen -t rsassh-copyid 用户名远程服务器地址start-dfs.sh chown [选项] 新所有者[:新所属组] 目标文件/目录常用选项&#xff1a;-R&#xff1a;递归修改目录下所有文件和子目录的所有者&#xff08;处理目录时常用&#xff09;-v&#xff1a;显示修改过程的详细信息-c&…

大模型入门实践指南

大模型入门教程:从概念到实践 大模型(Large Language Model, LLM)是当前人工智能领域的核心技术,其本质是通过大规模数据训练、具备复杂语言理解与生成能力的深度学习模型。本教程将从基础概念出发,带你理解大模型的核心逻辑,并通过可直接跑通的代码示例,快速上手大模型…

猫头虎开源AI分享:一款CSV to Chat AI工具,上传CSV文件提问,它可以即时返回统计结果和可视化图表

猫头虎开源AI分享&#xff1a;一款CSV to Chat AI工具&#xff0c;上传CSV文件提问&#xff0c;它可以即时返回统计结果和可视化图表 摘要 本文将详细介绍一款开源工具——CSV to Chat AI&#xff0c;它允许用户上传CSV文件并通过自然语言提问&#xff0c;系统会即时返回统计…

洛谷P9468 [EGOI 2023] Candy / 糖果题解

[EGOI 2023] Candy / 糖果 思路 NNN 这么小基本就是瞎打的 DP 了。 设 dpi,jdp_{i,j}dpi,j​ 为操作 jjj 次后前 iii 项的和最大是多少。 考虑转移&#xff0c;我们可以枚举 iii 并考虑将其移动到 ppp 位置&#xff0c;总共操作 kkk 次&#xff0c;那么就有 dpp,kmin⁡(dpp,…

AI智能体(Agent)大模型入门【3】--基于Chailit客服端实现页面AI对话

目录 前言 安装chailint 创建中文语言环境 创建chailint页面客户端 前言 本篇章将会基chailit框架实现页面进行AI对话。 若没有自己的本地模型对话&#xff0c;需要查看专栏内的文章&#xff0c;或者点击链接进行学习部署 AI智能体&#xff08;Agent&#xff09;大模型入…

【高并发内存池——项目】定长内存池——开胃小菜

提示&#xff1a;高并发内存池完整项目代码&#xff0c;在主页专栏项目中 文章目录 提示&#xff1a;高并发内存池完整项目代码&#xff0c;在主页专栏项目中 先设计一个定长的内存池 一、为什么需要定长内存池&#xff1f; &#x1f3e2; 传统内存分配的痛点 &#x1f3ed; 内…

6-获取磁盘分区信息

观察文件 获取server端电脑里面存在哪些盘符 int MakeDriveInfo() { //1>A 2>B &#xff08;原本属于软盘的 &#xff09;3>C ... 26>Zstd::string result;for (int i 1; i < 26; i) { //让其循环if (_chdrive(i) 0) //改变当前的驱动,_chdrive函数(c和c中)应…

每天认识一个电子器件之LED灯

LED选型核心参数一览表参数类别关键参数说明 & 为什么重要基本电气参数正向电压 (Vf)LED正常发光时两端的电压降。必须匹配您的电路电压。红/黄光约1.8-2.2V&#xff0c;蓝/绿/白光约2.8-3.6V。正向电流 (If)LED正常发光时所需的电流。决定了LED的亮度&#xff0c;必须用电…

Spring Boot 集成 Flowable 7.1.0 完整教程

一、引言 在企业级应用开发中&#xff0c;工作流管理是不可或缺的一部分。从简单的请假审批到复杂的业务流程&#xff0c;工作流引擎能够显著提升系统的灵活性和可维护性。​​Flowable​​ 作为一个轻量级、基于 Java 的开源工作流引擎&#xff0c;完美支持 ​​BPMN 2.0​​…