mysql菜鸟教程

专栏导航

13.3 索引类型:B树、哈希、全文索引

      MySQL 支持多种索引类型,每种类型都有其特定的数据结构、特点和适用场景。理解这些索引类型的区别,可以帮助你根据业务需求做出正确的选择,从而最大化查询性能。

一、B-Tree 索引(B+Tree)

B-Tree 索引(准确地说,MySQL 中使用的是 B+Tree)是 MySQL 中最常用、最通用的索引类型。InnoDB 和 MyISAM 存储引擎都默认使用 B-Tree 索引。

工作原理

B-Tree 索引将数据组织成一种平衡的多路查找树。在 B+Tree 中:

  • 所有实际数据(或指向数据的指针)都存储在叶子节点中。

  • 非叶子节点(内部节点)仅存储键值和指向子节点的指针,用于导航。

  • 叶子节点之间通过指针连接,形成一个有序链表,便于范围扫描。

这种结构使得 B-Tree 索引能够高效地支持:

  • 等值查询=IN

  • 范围查询><BETWEENLIKE 'prefix%'

  • 排序ORDER BY

  • 分组GROUP BY

特点

  • 有序性:索引列的值在叶子节点上有序存储,因此可以快速定位到任意值,也能高效进行范围扫描。

  • 多列索引支持:可以基于多个列创建复合索引,并遵循最左前缀原则。例如,索引 (a, b, c) 可以用于查询条件 a = ?a = ? AND b = ?a = ? AND b = ? AND c = ?,但不能直接用于 b = ? 或 c = ?

  • 适用所有数据类型:不仅适用于数值类型,也适用于字符串、日期等。

  • 性能稳定:无论数据量多大,查找时间通常为对数级别(O(log n))。

适用场景

  • 大多数业务查询,尤其是包含范围查找、排序或分组的情况。

  • 需要按索引列排序的场景。

  • 作为主键索引或唯一索引的底层实现。

二、哈希索引(Hash Index)

哈希索引基于哈希表实现。它通过计算索引列的哈希值来快速定位数据行,仅支持精确匹配查询。

工作原理

  • 对索引列的值应用哈希函数,计算出哈希码。

  • 哈希码映射到哈希表中的桶(bucket),桶中存储指向数据行的指针。

  • 查询时,对条件值计算哈希码,直接定位到对应的桶,从而找到数据行。

特点

  • 极速等值查询:哈希索引在 = 或 IN 查询中速度非常快,时间复杂度接近 O(1)。

  • 不支持范围查询:因为哈希后的值不再保持原有顺序,所以无法用于 ><BETWEEN 等范围条件。

  • 不支持排序:哈希索引本身无序,不能用于 ORDER BY

  • 可能存在哈希冲突:不同值可能产生相同哈希码,需要额外处理。

  • 不支持部分索引列查找:对于复合索引,哈希索引会使用所有列计算哈希值,不能单独用左前缀查找。

适用场景

  • Memory 存储引擎默认使用哈希索引(也支持 B-Tree)。

  • InnoDB 引擎中有一个特殊功能:自适应哈希索引(Adaptive Hash Index)。InnoDB 会在内存中根据频繁访问的 B-Tree 索引自动构建哈希索引,以加速等值查询,但对用户透明,无法手动干预。

  • 适用于查询模式单一、只有等值比较且对速度要求极高的场景。

三、全文索引(Full-Text Index)

全文索引专用于对文本内容进行关键词搜索,类似于搜索引擎的行为。它能够处理自然语言,找到包含特定单词或短语的记录。

工作原理

全文索引会对文本列进行分词,建立单词到文档位置的倒排索引。查询时,根据关键词快速定位包含该词的记录,并可按相关性排序。

特点

  • 支持自然语言搜索:可以查找包含某个单词的记录。

  • 支持布尔搜索:可使用 +-* 等操作符进行更精确的匹配(如必须包含某词、排除某词)。

  • 相关性排序:可以计算匹配度并返回按相关性排序的结果。

  • 忽略停用词:默认会忽略常见的无意义词(如“的”、“是”等,可配置)。

  • 对中文支持有限:MySQL 自带的全文索引对中文分词支持不佳,通常需要配合第三方分词插件(如 ngram)使用。

使用语法

全文索引需要使用特殊的 MATCH() AGAINST() 语法进行查询:


SELECT * FROM articles
WHERE MATCH(title, content) AGAINST('数据库' IN NATURAL LANGUAGE MODE);

适用场景

  • 文章、博客、新闻等内容检索系统。

  • 需要根据关键词搜索文本字段的业务。

  • 替代 LIKE '%keyword%' 的低效模糊查询。

限制

  • 仅支持 CHARVARCHARTEXT 类型的列。

  • 创建全文索引的列必须是这些文本类型。

  • 在 InnoDB 中,全文索引的维护成本较高,不适合频繁更新的列。

四、其他索引类型(补充)

虽然题目只列出了三种,但为了完整性,这里简单提一下其他索引类型:

  • 空间索引(SPATIAL):用于地理空间数据类型(如 GEOMETRYPOINT),基于 R-Tree 实现,支持空间数据的高效查询。

  • 聚集索引(Clustered Index):在 InnoDB 中,主键就是聚集索引,数据行实际存储在索引的叶子节点上。非聚集索引的叶子节点存储的是主键值,再通过主键查找完整数据行(回表)。

五、索引类型对比

B-Tree:

     底层数据结构: B+Tree

      支持查询类型: 等值、范围、排序、分组、前缀模糊

     适用场景: 大多数业务查询

     注意事项: 复合索引遵循最左前缀原则

哈希:

     底层数据结构: 哈希表

      支持查询类型: 等值

     适用场景: 极速等值查找,如缓存表

     注意事项: 不支持范围/排序,Memory引擎默认

全文:

     底层数据结构: 倒排索引

      支持查询类型: 关键词搜索、自然语言处理

     适用场景: 文本内容搜索

     注意事项: 对中文分词需特殊处理

六、如何选择合适的索引类型?

  • 如果你的查询涉及范围查找、排序或模糊匹配(LIKE 'prefix%'),首选 B-Tree 索引

  • 如果只有等值比较且对速度要求极高,可以考虑 哈希索引(通常使用 Memory 引擎或依赖 InnoDB 自适应哈希)。

  • 如果需要搜索文本内容中的单词,使用 全文索引

  • 不要混合使用多种索引在同一列上,通常一个列只需要一种索引(特殊需求除外)。

在实际设计时,应结合业务查询模式、数据分布和存储引擎特性综合权衡。


所有评论

关于我 备案号:蜀ICP备2023042032号-1