🗣 Wd提问: MySQL源码索引实现
🤖 Ai回答: MySQL 的索引实现主要依赖于其存储引擎(如 InnoDB、MyISAM 等),其中 InnoDB 是最常用、功能最完整的存储引擎,其索引结构基于 B+树(B-Tree Plus)。下面从源码角度解析 MySQL(以 InnoDB 为例)索引的实现原理。
🌟 一、核心数据结构
1、B+树结构
InnoDB 使用 B+树作为索引的底层数据结构,支持高效查找、插入、删除。
在源码中,B+树节点定义在:
`storage/innobase/include/btr0types.h`
c
struct btr_search_t; // 搜索路径缓存
struct btr_cur_t; // B+树游标
struct btr_pcur_t; // B+树物理游标
关键结构体:
`btr_search_t`:用于缓存搜索路径,提升后续查询性能。
`btr_cur_t`:表示当前在 B+树中的位置(类似游标),包含页指针、记录指针等。
`page_t`:代表一个数据页(16KB),是 B+树的基本单位。
📁 二、索引类型
InnoDB 支持以下索引:
主键索引(聚簇索引)
二级索引(非聚簇索引)
唯一索引、普通索引、前缀索引、联合索引等
所有索引都是 B+树结构,但主键索引叶子节点存储完整行数据(聚簇),二级索引叶子节点存储主键值(需回表)。
🔍 三、索引创建流程(源码级)
索引创建通过 SQL 解析后调用存储引擎接口:
`sql/sql_table.cc` → `ha_create_table()` → `innobase::create()` → `row_create_table_for_mysql()`
最终调用:
`storage/innobase/row/row0mysql.cc`
cpp
row_create_table_for_mysql(...)
{
...
dict_create_index(...); // 创建字典项
btr_create(...) // 创建B+树结构
...
}
关键函数:
`dict_create_index()`:创建索引元数据(在数据字典中)
`btr_create()`:实际创建 B+树结构(分配根页、初始化页)
🧱 四、B+树节点结构(源码视角)
每个 B+树节点是一个 页(page),大小默认 16KB。
页结构定义在:
`storage/innobase/include/page0types.h`
c
typedef struct page_struct {
byte* header; // 页头信息
byte* trailer; // 页尾校验
byte* data; // 数据区(记录)
} page_t;
页内记录组织方式:
记录按主键或索引键排序
使用 slot 数组(偏移量数组)快速定位记录
支持压缩、变长字段、溢出页等
🚀 五、索引查找过程(源码流程)
SQL 查询语句 → 优化器选择索引 → 存储引擎执行查找
关键函数:
`storage/innobase/row/row0sel.cc`
cpp
row_search_for_mysql(...)
{
btr_pcur_open(); // 打开游标
btr_pcur_search_to_nth_level(); // 从根节点开始搜索到叶节点
btr_pcur_get_rec(); // 获取目标记录
...
}
核心步骤:
1、从根节点开始:根据 key 值逐层向下查找
2、利用 search path cache:避免重复遍历相同路径
3、到达叶子节点:找到匹配记录或确定不存在
4、返回记录指针:供上层读取数据
🔄 六、索引插入与分裂(源码分析)
插入操作由 `btr_insert_into_node()` 处理:
`storage/innobase/btr/btr0cur.cc`
cpp
btr_insert_into_node(...)
{
if (page_full) {
btr_page_split(); // 分裂页面
}
...
}
页面分裂逻辑:
当页满时,分裂为两个页,中间键值上移到父节点
保持 B+树平衡
可能触发递归分裂(向上传播)
🗑️ 七、索引删除
删除操作调用:
`storage/innobase/btr/btr0cur.cc`
cpp
btr_delete_and_mark_compensate()
标记删除(延迟清理)
实际清理由 purge 线程处理
页面可能合并(如果记录太少)
💡 八、索引优化相关机制
1、自适应哈希索引(Adaptive Hash Index, AHI)
`storage/innobase/include/ut0rnd.h`, `storage/innobase/ha/ha0ha.cc`
根据访问模式自动为热点页建立哈希索引
加速等值查询
不持久化,重启后重建
2、Change Buffer(变更缓冲)
`storage/innobase/trx/trx0trx.cc`
延迟写入二级索引页,减少随机 I/O
合并多个修改后再刷盘
📊 九、源码目录结构概览
storage/innobase/
├── btr/ B+树相关:btr0cur.cc, btr0pcur.cc, btr0sea.cc
├── dict/ 数据字典:dict0dict.cc, dict0crea.cc
├── row/ 行操作:row0mysql.cc, row0sel.cc
├── include/
│ ├── btr0types.h
│ ├── page0types.h
│ └── dict0types.h
└── ha/ 存储引擎接口
✅ 十、总结:MySQL InnoDB 索引实现要点
| 特性 | 实现说明 |
| 数据结构 | B+树(平衡多路搜索树) |
| 页大小 | 默认 16KB,可配置 |
| 聚簇索引 | 主键索引,叶子节点存完整行数据 |
| 二级索引 | 叶子节点存主键,需回表 |
| 插入/删除 | 自动分裂/合并,保持平衡 |
| 缓存机制 | Search Path Cache, AHI, Change Buffer |
| 并发控制 | 使用锁和 MVCC 保证一致性 |
| 持久化 | 索引结构随数据一起写入 redo log 和磁盘 |
📚 参考资料
MySQL 官方文档:https://dev.mysql.com/doc/refman/8.0/en/innodb-index-types.html
InnoDB 源码仓库:https://github.com/mysql/mysql-server
《MySQL技术内幕:InnoDB存储引擎》——姜承尧
《高性能MySQL》——Baron Schwartz 等
如果你希望深入某个具体函数(如 `btr_search_to_nth_level`)或想了解索引统计信息如何维护,可以继续提问,我可以为你展开源码细节 😊
📣 商家广告:





0
IP地址: 212.247.90.219
搜索次数: 0
提问时间: 2025-11-11 07:06:47
🛒 域名购买:
zqll.cn
lansou.cn
gz.gold
6.ac.cn
r-t.com.cn
9-9.net
wenchangji.cn
62.gs
oz.gs
97.gold
❓️ 热门提问:
crps服务器电源
网站虚拟空间
ai后缀域名
注册域名需要多少钱
PHP源码部署到服务器
电子商务网站建设
vps sps pps
ip root
北京网站开发公司哪家好
北京虚拟主机
豌豆Ai站群搜索引擎系统
🌐 域名评估:
yu7.ah.cn
vv.jl.cn
kk.ah.cn
vtol.ac.cn
au.cq.cn
qq.com
gouc.cn
aaa.mo.cn
su8.sh.cn
catl.ha.cn
⛏ 最新挖掘:
凯里酸汤鱼
贵阳烤脑花
都匀毛尖茶
花溪牛肉粉
贵阳烤生蚝
贵阳烤豆腐
贵阳纸包鱼
贵阳特色菜
🖌 热门作画:
🤝 关于我们:
豌豆Ai
域名
建站
站群
留痕
推广
评估
源码
开发Ai
工具
日记
价格
加盟
广告
流量
留言
联系
🗨 加入群聊:
🔗 友情链接:
サーチエンジンプログラム
搜全网
ai提问
🧰 站长工具:
Ai工具 whois查询 搜索
📢 温馨提示:本站所有问答由Ai自动创作,内容仅供参考,若有误差请用“联系”里面信息通知我们人工修改或删除。
👉 技术支持:本站由豌豆Ai提供技术支持,使用的最新版:《豌豆Ai站群搜索引擎系统 V.25.10.25》搭建本站。