尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

为什么 InnoDB 选择 B+树做索引?——从磁盘I/O到数据结构选型

为什么 InnoDB 选择 B+树做索引?——从磁盘I/O到数据结构选型 一、索引面临的核心挑战在讨论具体数据结构之前先要理解数据库索引面临的特殊场景· 数据存储在磁盘索引本身很大无法全部装入内存只能以索引文件形式存储在磁盘上· 磁盘I/O是瓶颈内存访问是纳秒级磁盘访问是毫秒级两者相差上万倍甚至几十万倍· 查询类型多样不仅要支持等值查询还要支持范围查询、排序等操作这意味着索引数据结构的设计核心目标就是尽可能减少磁盘I/O次数。二、为什么二叉树不行二叉搜索树BST平均查找复杂度为 O(log n)看似不错但存在致命缺陷退化问题如果插入的数据是有序的如自增主键 1,2,3,4,5二叉树会退化成链表时间复杂度变为 O(n)。即使引入AVL树、红黑树等自平衡二叉树依然不适合作为数据库索引——每个节点只存储一个键值一次磁盘I/O只能获取一个关键字。100万条记录的平衡二叉树需要约20次查找也就意味着最多20次磁盘I/O效率极低。三、为什么哈希表不行哈希表等值查询效率极高O(1)但存在两个致命问题· 无法支持范围查询哈希打乱了数据的有序性无法支持 WHERE id BETWEEN 10 AND 100 这类操作· 无法支持排序哈希索引不能用于 ORDER BY而范围查询和排序恰恰是数据库中极其常见的操作。四、B树为磁盘而生但仍有不足B树是多路平衡搜索树每个节点可存储多个关键字节点大小通常设计为一个磁盘页如16KB。一个阶数为100的B树三层即可容纳约100万条记录最多3次磁盘I/O即可完成查找。但B树仍有不足内部节点也存数据每个节点都存储关键字和数据或数据指针导致每个节点能容纳的关键字数量受限树高难以降到最低范围查询效率不高需要进行中序遍历整棵树无法高效连续访问五、B树为数据库索引而生的最优解B树在B树基础上做了两项关键改进① 数据仅存于叶子节点内部节点只存索引② 叶子节点通过双向链表连接这两个特性带来了决定性的优势优势一极低的树高 → 磁盘I/O次数最少由于内部节点不存储数据只存键和指针同样大小的磁盘页可以容纳更多的索引条目。以InnoDB为例默认页大小为16KB主键为BIGINT8字节 指针6字节 14字节· 每个内部节点可存约 16×1024 / 14 ≈ 1170 个索引条目· 两层B树可索引约136万条记录三层可达16亿条以上而高度仅为3这意味着查询任意一条数据最多只需2~3次磁盘I/O。InnoDB还将根节点常驻内存实际查询时I/O次数更少。相比之下B树由于内部节点也要存数据同样数据量下树更高I/O次数更多。优势二范围查询效率极高B树的所有叶子节点通过双向链表串联成有序链表。进行范围查询时只需从起点叶子节点开始沿着链表向后遍历即可。而B树需要进行中序遍历整棵树效率远低于B树。优势三查询性能极其稳定B树中所有数据都在叶子节点任何查询都必须从根节点走到叶子节点所有查询的路径长度相同。而B树中数据分布在各层节点运气好根节点就能命中运气差要到叶子节点查询时间波动很大。优势四全表扫描更高效全表扫描时B树只需扫描叶子节点链表即可而B树需要遍历整棵树的所有节点。六、InnoDB中的B树实现InnoDB对B树做了特定实现和优化· 聚簇索引叶子节点直接存储完整行数据主键索引即数据本身· 二级索引叶子节点存储主键值查询时需回表· 页分裂当页满时插入新数据会触发页分裂涉及磁盘I/O和指针更新· B树高度通常为2~4层即使千万级数据也只需少量I/O七、总结数据结构等值查询范围查询磁盘I/O次数MySQL选型二叉树O(log n)差高约20次/百万数据❌哈希表O(1)不支持低❌仅辅助B树O(log n)一般中等❌B树O(log n)极优最低2~3次✅InnoDB选择B树的根本原因可以归结为一句话在磁盘I/O是最大瓶颈的背景下B树通过「内部节点只存索引 叶子节点链表」的设计以最低的树高、最少的I/O次数、最稳定的查询性能同时完美支持了等值查询和范围查询两大核心场景。技术选型从来不是凭空而来——B树是InnoDB在磁盘I/O效率、查询性能和数据结构复杂度之间找到的最优平衡点。
返回列表