MYSQL 索引与数据结构笔记


文章目录

  • MYSQL 索引与数据结构笔记
    • 1. B-Tree 与 B+ Tree 基础对比
      • 一、B 树的优势
      • 二、B 树的进一步优化
      • 三、综合对比
      • 结论
    • 2. MySQL 为何选择 B+ Tree
    • 3. 索引使用示例与性能分析
      • 3.1 整数字段索引查询
      • 3.2 字符字段索引查询
    • 4. 索引失效与类型转换陷阱
    • 5. 小结


1. B-Tree 与 B+ Tree 基础对比

  • B-Tree(平衡树)
    • 每个节点既存储 (Key),也存储 实际数据(Data)。
    • 查找时从根节点(Root)开始,沿着指针遍历至叶节点(Leaf),每次节点访问都可能触发一次磁盘 I/O。
    • 特点:小的键在左,大的键在右,定位单条记录的最坏深度与树高成正比。
  • B+ Tree(平衡树加强版)
    • 非叶子节点 只存储 ,不存储数据;所有数据集中存放于 叶子节点
    • 叶子节点之间通过双向链表相连,支持范围查询时从起始叶节点依次遍历,无需回到根节点重复搜索。
    • 由于非叶子节点仅存键,可在同页面存储更多索引,树更“宽”、高度更浅,减少索引查找的磁盘 I/O 次数。

以上图示直观对比了两者的结构差异:

  • B-Tree 左侧,内外节点均存数据;
  • B+ Tree 右侧,内部节点只有键,叶子通过链表横向连接。

B 树相比其他数据结构为何更快?B 树又如何进一步提升性能?


一、B 树的优势

  1. 高扇出(Fan-out)、低高度
    • B 树的每个节点(页面)可以包含 m 个子指针和 m–1 个关键字,通常 m 很大(几百到上千),因为页面大小(如 16 KB)可容纳大量记录指针。
    • 相比二叉搜索树(每节点仅 2 个子指针),B 树树高明显更低:
      高度 ≈ log ⁡ m N ≪ log ⁡ 2 N \text{高度} \approx \log_{m}N \ll \log_{2}N 高度logmNlog2N
    • 结果:每次查询只需少量层次的磁盘 I/O。
  2. 磁盘友好:“页面+批量读写”
    • 节点大小与磁盘块(页面)大小匹配,一次 I/O 就能读取或写入一个完整节点。
    • 大量连续指针和键值在同一页面中,最大化单次 I/O 的有效数据利用率。
  3. 动态平衡
    • B 树在插入/删除时始终保持平衡,无需昂贵的旋转操作(区别于 AVL、红黑树)。
    • 分裂/合并操作较少,且都局限在少数相邻节点,引发的页面写回有限。
  4. 支持范围查询(部分)
    • 虽非链表连接,B 树也能通过中序遍历叶子节点进行范围扫描,复杂度 O ( log ⁡ m N + K ) O(\log_m N + K) O(logmN+K),其中 K 是返回行数。

二、B 树的进一步优化

在 B 树基础上,B+ 树对 I/O 和范围查询做了两点关键改进:

  1. 非叶子节点只存“路由键”
    • B 树:每个节点都存键+数据指针。
    • B+ 树
      • 内部节点:仅存 和子指针,页内可容纳更多分支,进一步提升扇出 m m m
      • 叶子节点:存所有 键 + 数据指针
    • 好处:更宽的树 → 更浅的树 → 更少层级 I/O。
  2. 叶子节点双向链表
    • 所有叶子通过指针串联,形成线性链表。
    • 范围查询
      1. 定位首条记录( log ⁡ m N \log_m N logmN 次 I/O)。
      2. 顺链遍历后续叶子页,每页一次 I/O,即可连续获取大量记录,无需再回到根节点。
    • 预取优化:操作系统或 InnoDB 可预测地提前读取下几页,减少读取延迟。

三、综合对比

特性二叉树 / AVL / 红黑树B 树B+ 树
树高 Θ ( log ⁡ 2 N ) \Theta(\log_2 N) Θ(log2N) Θ ( log ⁡ m N ) \Theta(\log_m N) Θ(logmN) Θ ( log ⁡ m N ) \Theta(\log_m N) Θ(logmN)(更小)
每层 I/O1 个节点(小)1 个大页面1 个更大分支数大页面
插入/删除旋转、重染色开销大分裂/合并局部节点同 B 树,节点更少分裂
范围查询需要中序多次回溯叶子遍历可中序,但无链表需回根首查后链表顺序遍历,高效顺序读取
磁盘利用率无页面概念,非批量 I/O每页批量同 B 树,更多指针→更高页面利用率

结论

  • B 树 相比纯内存二叉结构,更贴合磁盘 I/O 模型:高扇出、低树高、少 I/O。
  • B+ 树 在此基础上:
    • 更高扇出(节点更“瘦”),进一步压低树高;
    • 链表化叶子,极大优化范围扫描和预取,减少随即 I/O。

这种设计正好契合数据库对“大量数据+高并发读写+范围查询”场景的需求,因而被广泛采用,MySQL InnoDB 默认索引即基于 B+ 树。


2. MySQL 为何选择 B+ Tree

  1. 更少的磁盘 I/O

    • 叶子节点更集中,树高度更低。
    • 访问任意数据最多经过 ⌈ log ⁡ m N ⌉ \lceil \log_{m}N\rceil logmN层,且每层页面能存更多指针。
  2. 高效的范围查询

    • 双向链表链通所有叶节点。
    • 查询 [low, high] 时,从根定位 low,再顺链查到 high,无需多次回根。
  3. 页面利用更高

    • 非叶子节点仅存键,单页指针更多。
    • 更少分裂、重平衡次数,维护成本更低。

3. 索引使用示例与性能分析

假设有如下测试表:

CREATE TABLE t_demo (id_int INT NOT NULL PRIMARY KEY,id_char CHAR(10),INDEX idx_char (id_char)
);

INDEX / KEY

  • 在 SQL 标准中,INDEX 用于指示“给某列建立额外的索引结构”;MySQL 中 INDEXKEY 同义。
  • 作用:加速基于该列的查找(=IN)、排序(ORDER BY)、范围扫描(BETWEEN><)等操作。
  • 类型
    • 普通索引(Secondary Index):如上例 idx_char,只存列值 + 聚簇主键,用于辅助查找。
    • 唯一索引(UNIQUE INDEX):加上 UNIQUE 关键字,保证列值不重复。
    • 全文索引(FULLTEXT):用于自然语言全文检索。
    • 空间索引(SPATIAL):针对 GIS 数据。

idx_char

  • 这是索引的名字,必须在同表内唯一。

  • 建议命名习惯:idx_<列名>idx_<表名>_<列名>,便于维护和阅读。

  • 用途示例:

    SHOW INDEX FROM t_demo;
    -- 你会看到一个名为 idx_char 的索引,Column_name: id_char
    DROP INDEX idx_char ON t_demo;
    

聚簇索引 vs 辅助索引

  • 聚簇索引(Clustered Index)
    • 由 InnoDB 强制由主键构建。
    • 叶子节点直接存放整行数据(行记录)。
  • 辅助索引(Secondary Index)
    • 叶子节点只存「索引列值 + 主键列值」。
    • 查到主键后,再回聚簇索引查整行。

3.1 整数字段索引查询

EXPLAIN SELECT * FROM t_demo WHERE id_int = 3;
  • Output: key: PRIMARY, rows: 1
  • 利用聚簇索引,直接定位叶节点,一个 I/O 即可返回数据。
  • EXPLAIN 用于让 MySQL 优化器输出该查询的“执行计划”,常见字段:
列名含义
id查询标识,表示第几条子查询或联合查询
select_type查询类型,如 SIMPLE(简单查询)、PRIMARY、SUBQUERY 等
table本行描述的是哪张表
type访问类型,从好到差:system / const / eq_ref / ref / range / ALL
possible_keys优化器认为可用的索引列表
key实际使用的索引
key_len使用索引的字节长度
ref哪个列或常量与索引列比较
rows估算需要扫描的行数
filtered估算有多少百分比的行会被 WHERE 过滤
Extra额外信息,如 Using index(覆盖索引)、Using filesortUsing temporary

image-20250510134526863


3.2 字符字段索引查询

EXPLAIN SELECT * FROM t_demo WHERE id_char = 'three';
  • Output: key: idx_char, rows: 1
  • 较整型略慢,但依然通过二分定位叶节点和链表读取。

image-20250510134511956


4. 索引失效与类型转换陷阱

当对 索引字段 应用函数或运算时,会导致 MySQL 无法利用索引,转而全表扫描,示例如下:

EXPLAIN SELECT * FROM t_demo WHERE id_int + 0 = 1;
-- key: NULL, rows: 全表扫描

image-20250510134458178

原因:

  • 聚簇索引的页内顺序被打乱,MySQL 无法在叶节点上直接比较。
  • 索引失效后,每行先转换再比较,磁盘 I/O 和 CPU 转换开销剧增。

最佳实践

  • 避免在 WHERE 条件中对索引列进行任何运算或类型转换。

  • 如需偏移量查询,可将常量移至列右侧:

    -- 建议
    SELECT * FROM t_demo WHERE id_int = 1 - 0;
    -- 避免
    SELECT * FROM t_demo WHERE id_int + 0 = 1;
    
  • 对于范围查询(如 BETWEEN><),只要不对字段本身改动,即可走范围索引。

image-20250510134440298


5. 小结

  • B+ Tree:MySQL 默认索引结构,专为大规模数据检索优化。
  • 范围查询:链表加速,极大提升大数据下的连续扫描性能。
  • 索引失效:对索引列的任何计算或类型转换都会导致全表扫描,严重影响性能。

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

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

相关文章

电路中的DGND、GROUND、GROUND_REF的区别,VREF、VCC、VDD、VEE和VSS的区别?

目录 1 DGND、GROUND、GROUND_REF的区别 1.1 DGND&#xff08;Digital Ground&#xff09; 1.2 GROUND&#xff08;Ground&#xff09; 1.3 GROUND_REF&#xff08;Ground Reference&#xff09; 1.4 区别 2 VREF、VCC、VDD、VEE和VSS的区别 2.1 VREF&#xff08;Refere…

OpenHarmony平台驱动开发(十),MMC

OpenHarmony平台驱动开发&#xff08;十&#xff09; MMC 概述 功能简介 MMC&#xff08;MultiMedia Card&#xff09;即多媒体卡&#xff0c;是一种用于固态非易失性存储的小体积大容量的快闪存储卡。 MMC后续泛指一个接口协定&#xff08;一种卡式&#xff09;&#xff0…

C++ 的 VS 项目中引入跨平台包管理工具 conan

我们知道 C 不像很多其他语言有包管理工具&#xff0c;比如 Python 有 pip&#xff0c;Java 有 maven&#xff0c;C# 有 nuget&#xff0c;JS 有 npm&#xff0c;Go 有 go mod&#xff0c;Rust 有 cargo&#xff0c;项目中需要自己手动引入第三方库&#xff0c;手动维护带来了很…

vscode 默认环境路径

1.下面放在项目根目录上&#xff1a; .vscode/settings.json 2.settings.json内容&#xff1a; {"python.analysis.extraPaths": ["${workspaceFolder}"],"python.defaultInterpreterPath": "/shared_disk/users/lbg/envs/py310_see3d/b…

Android 项目中配置了多个 maven 仓库,但依赖还是下载失败,除了使用代理,还有其他方法吗?

文章目录 前言解决方案gradlemaven 仓库 前言 我们在Android 开发的过程中&#xff0c;经常会遇到三方依赖下载不下来的问题。一般情况下我们会在项目的build.gradle文件中配置多个 maven 仓库来解决。 // Top-level build file where you can add configuration options com…

uni-app 引入vconsole web端正常,安卓端报错 Cannot read property ‘sendBeacon‘ of undefined

reportJSException >>>> exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack ->Uncaught TypeError: Cannot read property sendBeacon of undefined vconsole 只支持 web 端&#xff0c;…

火山RTC 7 获得远端裸数据

一、获得远端裸数据 1、获得h264数据 1&#xff09;、远端编码后视频数据监测器 /*** locale zh* type callback* region 视频管理* brief 远端编码后视频数据监测器<br>* 注意&#xff1a;回调函数是在 SDK 内部线程&#xff08;非 UI 线程&#xff09;同步抛出来的&a…

web 自动化之 Unittest 四大组件

文章目录 一、如何开展自动化测试1、项目需求分析&#xff0c;了解业务需求 web 功能纳入自动化测试2、选择何种方式实现自动化测试 二、Unittest 框架三、TestCase 测试用例四、TestFixture 测试夹具 执行测试用例前的前置操作及后置操作五、TestSuite 测试套件 & TestLoa…

42、在.NET 中能够将⾮静态的⽅法覆写成静态⽅法吗?

在.NET中&#xff0c;不能将非静态方法&#xff08;实例方法&#xff09;直接覆写&#xff08;Override&#xff09;为静态方法&#xff08;Static Method&#xff09;。以下是关键原因和解释&#xff1a; 1. 方法绑定的本质区别 实例方法&#xff1a;属于对象的实例&#xf…

8天Python从入门到精通【itheima】-1~5

目录 1节&#xff1a; 1.Python的优势&#xff1a; 2.Python的独具优势的特点&#xff1a; 2节-初识Python&#xff1a; 1.Python的起源 2.Python广泛的适用面&#xff1a; 3节-什么是编程语言&#xff1a; 1.编程语言的作用&#xff1a; 2.编程语言的好处&#xff1a;…

3D迷宫探险:伪3D渲染与运动控制的数学重构

目录 3D迷宫探险:伪3D渲染与运动控制的数学重构引言第一章 伪3D渲染引擎1.1 射线投射原理1.2 纹理透视校正第二章 迷宫生成算法2.1 图论生成模型2.2 复杂度控制第三章 第一人称控制3.1 运动微分方程3.2 鼠标视角控制第四章 碰撞检测优化4.1 层级检测体系4.2 滑动响应算法第五章…

mac一键安装gpt-sovit教程中,homebrew卡住不动的问题

mac一键安装gpt-sovit教程 仅作为安装过程中解决homebrew卡住问题的记录 资源地址 https://www.yuque.com/baicaigongchang1145haoyuangong/ib3g1e/znoph9dtetg437xb#mlAoP 下载一键包 下载后并解压&#xff0c;找到install for mac.sh&#xff0c;终端执行bash空格拖拽in…

git 远程仓库管理详解

Git 的远程仓库管理是多人协作和代码共享的核心功能。以下是 Git 远程仓库管理的详细说明&#xff0c;包括常用操作、命令和最佳实践。 1. 什么是远程仓库&#xff1f; 远程仓库&#xff08;Remote Repository&#xff09;&#xff1a;存储在网络服务器上的 Git 仓库&#xff0…

【超详细教程】安卓模拟器如何添加本地文件?音乐/照片/视频一键导入!

作为一名安卓开发者或手游爱好者&#xff0c;安卓模拟器是我们日常工作和娱乐的重要工具。但很多新手在使用过程中常常遇到一个共同问题&#xff1a;**如何将电脑本地的音乐、照片、视频等文件导入到安卓模拟器中&#xff1f;**今天&#xff0c;我将为大家带来一份全网最详细的…

使用vite重构vue-cli的vue3项目

一、修改依赖 首先修改 package.json&#xff0c;修改启动方式与相应依赖 移除vue-cli并下载vite相关依赖&#xff0c;注意一些peerDependency如fast-glob需要手动下载 # 移除 vue-cli 相关依赖 npm remove vue/cli-plugin-babel vue/cli-plugin-eslint vue/cli-plugin-rout…

uniapp|实现手机通讯录、首字母快捷导航功能、多端兼容(H5、微信小程序、APP)

基于uniapp实现带首字母快捷导航的通讯录功能,通过拼音转换库实现汉字姓名首字母提取与分类,结合uniapp的scroll-view组件与pageScrollTo API完成滚动定位交互,并引入uni-indexed-list插件优化索引栏性能。 目录 核心功能实现动态索引栏生成​联系人列表渲染​滚动定位联动性…

C#中SetProperty方法使用

SetProperty 是 MVVM&#xff08;Model-View-ViewModel&#xff09; 模式中用于实现 属性变更通知&#xff08;INotifyPropertyChanged&#xff09; 的核心方法&#xff0c;主要用于在属性值变化时自动更新 UI 绑定。 1. SetProperty 的基本作用 更新字段值&#xff1a;修改属性…

MYSQL 全量,增量备份与恢复

目录 一 数据备份的重要性 1 数据备份的重要性 2 数据库备份类型 2.1 从物理与逻辑的角度分类 2.2. 从数据库的备份策略角度分类从数据库的备份策略角度,数据库的备份可分为完全备份、差异备份和增量备份。 3 常见的备份方法 3.1 物理冷备份 物理冷备份时需要在数据库处…

豆瓣电影Top250数据工程实践:从爬虫到智能存储的技术演进(含完整代码)

目录 引言:当豆瓣榜单遇见大数据技术 项目文档 1.1 选题背景 1.2 项目目标 2. 项目概述 2.1 系统架构设计 2.2 技术选型 2.3 项目环境搭建 2.3.1 基础环境准备 2.3.2 爬虫环境配置 2.3.3 Docker安装ES连接Kibana 安装IK插件 2.3.4 vscode依赖服务安装 3. 核心模…

深度 |国产操作系统“破茧而出”:鸿蒙电脑填补自主生态空白

真心为国内能有像华为这样的技术型公司而自豪&#xff0c;一步步突围技术封锁。从这篇信息&#xff0c;可以给软件从业者一个启示&#xff1a;鸿蒙生态将是一个新的机会&#xff0c;值得好好把握。 鸿蒙电脑正成为中国电子信息技术新坐标。 超10亿鸿蒙生态设备、2800家鸿蒙智…