MySQL中说的“B树索引”实际是B+树索引,因B+树所有数据存于叶子节点、叶子间有双向链表、查询路径固定,更适配磁盘I/O与范围查询;主键索引叶子存整行,二级索引叶子存列值+主键,需回表;函数、隐式转换、前导模糊匹配等会使索引失效。
MySQL 中说的“B树索引”,实际指的是 B+树索引,这是 InnoDB 和 MyISAM 存储引擎默认采用的索引结构。虽然官方文档和用户常统称其为“B树索引”,但底层实现严格来说是 B+树——它在磁盘 I/O 效率、范围查询和顺序访问方面比经典 B 树更适配数据库场景。
核心原因在于数据库运行在磁盘上,而磁盘读写以“页”(page)为单位(InnoDB 默认 16KB)。B+树做了三项关键优化:
WHERE id BETWEEN 100 AND 200)和顺序扫描(ORDER BY)以主键索引为例(即聚集索引):
整个过程最多只需 2~3 次磁盘 I/O(取决于数据量),远优于全表扫描的 O(n) 成本。
关键差异在叶子节点存储内容:
比如建了 INDEX idx_name ON users(name),执行 SELECT * FROM users WHERE name = 'Alice' 就会先走二级索引找到主键 ID,再拿这个 ID 去主键索引里捞整行——这叫“回表查询”。若只查 SELECT id, name,且索引已覆盖,则无需回表(覆盖索引优化)。
即使建了索引,以下情况仍可能导致全表扫描:
WHERE YEAR(create_time) = 2025
WHERE phone = 13800138000(phone
是 VARCHAR,数字会触发转换)WHERE name LIKE '%li'(无法利用索引的有序性)WHERE a = 1 OR b = 2,若 b 列没索引,可能放弃整个索引WHERE score * 2 > 100
这些本质上都破坏了 B+树按 key 有序遍历的能力,使优化器选择放弃索引。