首页 >> 基础教程

mysql中B+树索引和 Hash 索引有什么区别?

在 MySQL 中,B+树索引和 Hash 索引是两种完全不同的索引结构,它们各有优缺点,适用于不同的查询场景。主要区别如下:

特性

B+树索引

Hash 索引

数据结构

多路平衡搜索树(有序结构)

哈希表(无序结构)

查询类型支持

等值查询
范围查询(><BETWEEN
排序(ORDER BY
模糊查询(前缀匹配 LIKE 'abc%'

仅支持等值查询(=IN()
不支持范围查询
不支持排序
不支持模糊查询

查询效率

等值查询:O(logₙN)(稳定)
范围查询:高效(叶子节点链表)

等值查询:O(1)(理想情况下,极快)
范围查询:不支持

排序支持

天然有序(叶子节点构成链表)

无序(需额外排序操作)

磁盘 I/O 优化

适合磁盘存储(减少 I/O 次数,顺序访问友好)

随机访问多,可能引发更多 I/O

空间利用率

较高(节点填充因子高)

较低(哈希冲突、扩容开销)

索引列重复值

高效处理

哈希冲突影响性能

使用场景

OLTP 主流选择、范围查询、排序、高并发

内存表、精确点查场景、临时表、自适应哈希索引

存储引擎支持

InnoDB(默认)、MyISAM

仅 Memory 引擎显式支持
(InnoDB 有自适应哈希索引)

  1. 数据结构与基本原理
  • B+树索引: 基于 多路平衡搜索树。数据存储在有序的叶子节点中(形成链表),非叶子节点只存储键值和指向子节点的指针。查询从根节点开始,逐层比较键值,最终定位到叶子节点。

  • Hash 索引: 基于 哈希表。对索引列的值计算一个哈希码(Hash Code),然后将指向数据行的指针存储在哈希表中对应的“桶”(Bucket)里。查询时直接计算键值的哈希码,找到对应的桶(理想情况下时间复杂度 O(1)),再在桶内精确匹配(解决哈希冲突)。

  1. 支持的查询类型

  2. B+树索引:

  3. 等值查询: WHERE column = value

  4. 范围查询: WHERE column > valueWHERE column BETWEEN value1 AND value2 等。因为数据在叶子节点是有序存储的。

  5. 排序: ORDER BY column。利用叶子节点的链表结构可以高效地按顺序获取数据。

  6. 前缀匹配模糊查询: WHERE column LIKE 'prefix%'。可以利用索引的最左前缀特性。

  7. Hash 索引:

  8. 仅支持等值查询: WHERE column = value 或 WHERE column IN (value1, value2, ...)

  9. 不支持范围查询: 因为哈希表本身是无序的,无法高效定位一个范围。

  10. 不支持排序: 无序性导致无法利用索引进行排序。

  11. 不支持模糊查询: 即使是最左前缀 LIKE 'abc%' 也不行,因为哈希函数是对整个值计算的。

  12. 查询效率

  13. B+树索引: 等值查询效率是 O(logₙN)(N 是记录数,n 是节点扇出),非常高效且稳定。范围查询效率也很高,因为只需要定位到范围的起始点,然后顺序扫描叶子节点链表即可。

  14. Hash 索引: 在没有哈希冲突的理想情况下,等值查询效率是 O(1),理论上比 B+树更快。但是:

  15. 哈希冲突会降低效率(需要遍历冲突链)。

  16. 范围查询或排序需要全表扫描,效率极低。

  17. 磁盘 I/O 友好性

  18. B+树索引: 设计时充分考虑了磁盘存储特性。树的高度较低(通常 3-4 层就能存储海量数据),每次查询只需几次磁盘 I/O。顺序访问(范围扫描)效率高。

  19. Hash 索引: 哈希查找本质上是随机 I/O。桶的位置由哈希函数决定,没有局部性原理。当索引无法完全放入内存时,大量的随机磁盘 I/O 会严重拖慢速度。这是 Hash 索引在磁盘数据库中应用受限的关键原因。

  20. 空间利用率

  21. B+树索引: 空间利用率较高。节点通常填充较满(InnoDB 页默认 16KB)。

  22. Hash 索引: 为了减少冲突,哈希表通常需要更大的空间(负载因子小于 1)。桶的数量需要精心管理,扩容(Rehashing)操作开销大。

  23. 对索引列重复值的处理

  24. B+树索引: 可以高效处理重复键值。相同键值的记录会存储在相邻的叶子节点位置(具体实现如 InnoDB 会附加主键保证唯一性)。

  25. Hash 索引: 大量重复键值会导致严重的哈希冲突,显著降低查询效率。

MySQL 中的实际应用

  1. 显式 Hash 索引: 只有 MEMORY 存储引擎显式支持创建 Hash 索引。因为它将数据完全存储在内存中,规避了 Hash 索引随机 I/O 的致命缺点。

  2. InnoDB 的 Adaptive Hash Index: InnoDB 存储引擎有一个自适应哈希索引特性。它是一个内置的、自动的、透明的优化机制。

  3. 原理: InnoDB 监控对表上 B+树索引的查询模式。如果发现某些索引值(或其前缀)被非常频繁地以等值查询方式访问,它会在内存中的 Buffer Pool 里为这些热点值自动创建一个 Hash 索引指向 B+树叶子节点上的真实记录。

  4. 目的: 加速这些特定热点值的查询速度,使其接近 O(1)。

  5. 用户控制: DBA 可以开启或关闭该特性(innodb_adaptive_hash_index),或调整其分区数(innodb_adaptive_hash_index_parts)以降低锁争用。

  6. 关键点:

  7. 它是对 B+树索引的补充,不是替代。

  8. 它只针对频繁访问的特定值。

  9. 它完全由 InnoDB 内部管理,用户无法手动创建或指定哪些列使用 AHI。

  10. 它利用的是内存 Buffer Pool,不解决磁盘 I/O 问题。

  11. NDB Cluster 引擎: 也使用了 Hash 索引作为其主要的索引类型。

所有评论

最新文章
20.5 性能优化建议2026-05-08
20.4 复杂查询实现2026-05-08
20.3 表创建与数据初始化2026-05-08
20.2 数据库设计2026-05-08
20.1 项目需求分析:博客系统2026-05-08
19.4 自动化备份策略2026-05-08
19.3 导出和导入数据2026-05-08
19.2 恢复备份数据2026-05-05
19.1 使用mysqldump备份数据2026-05-05
18.4 实战:开发简单的学生管理系统2026-05-05
关于我 备案号:蜀ICP备2023042032号-1