MySQL 索引分类 实现原理

48

MySQL索引是优化查询速度的关键机制,其分类和实现原理如下

索引分类

按数据结构划分

B+Tree索引

最常见类型,InnoDB和MyISAM引擎的默认索引。

支持范围查询、排序和模糊匹配(如LIKE 'abc%')。

哈希索引

基于哈希表实现,仅Memory引擎显式支持。

仅支持等值查询(=、IN()),速度快但不支持范围查询。

全文索引(FULLTEXT)

用于文本内容的搜索(如MATCH ... AGAINST),基于倒排索引实现。

支持分词和关键词匹配,适用于大段文本检索。

空间索引(R-Tree)

用于地理空间数据(如GIS类型的GEOMETRY),支持空间范围查询。

按功能约束划分

主键索引(PRIMARY KEY):唯一且非空,每个表只能有一个,叶子节点存储行数据(InnoDB聚簇索引)。

唯一索引(UNIQUE):列值唯一,允许NULL值,用于保证数据唯一性。

普通索引(INDEX/KEY):无唯一性约束,仅加速查询。

组合索引(复合索引):多列组合的索引,遵循最左前缀原则(如索引(a,b,c)可优化WHERE a=1 AND b=2,但无法优化WHERE b=2)。

按存储方式划分

聚簇索引 (Clustered Index):数据行直接存储在索引的叶子节点(如InnoDB的主键索引),表数据按索引顺序物理存储。

非聚簇索引(Secondary Index):叶子节点存储主键值,需回表查询数据(如InnoDB的二级索引)。

底层实现原理

B+Tree索引

结构特点

多路平衡搜索树:非叶子节点仅存储键值和子节点指针,叶子节点存储数据(或主键)并按顺序双向链接。

高扇出性:单个节点可存储大量键,降低树的高度(通常3~4层即可存储亿级数据)。

优势

范围查询高效(叶子节点链表顺序扫描)。

查询稳定性高(所有查询均需遍历到叶子节点,时间复杂度稳定为O(log N))。

InnoDB实现细节

主键索引为聚簇索引,叶子节点存储行数据。

二级索引叶子节点存储主键值,查询时需通过主键回表获取数据。

哈希索引

实现方式:哈希表结构,通过哈希函数将键值映射到桶中,每个桶存储指向数据行的指针。

局限性:

无法支持范围查询、排序及部分模糊查询(如LIKE '%abc')。

等值查询快(O(1)),但哈希冲突可能影响性能。

全文索引

倒排索引(Inverted Index)

记录单词到文档ID的映射,并存储单词位置信息。

分词后建立索引,支持关键词匹配和相关性评分。

组合索引与最左前缀

最左前缀原则

索引(a,b,c)可优化以下查询:

✅ WHERE a=1

✅ WHERE a=1 AND b=2

✅ WHERE a=1 AND b=2 AND c=3

❌ WHERE b=2(无法使用索引)

索引跳跃扫描(MySQL 8.0+)

部分场景下可绕过最左前缀限制,但通常建议按索引顺序编写查询条件。

存储引擎差异

关键优化点

覆盖索引:查询列均在索引中时,避免回表(如SELECT a FROM table WHERE a=1)。

索引下推(ICP):MySQL 5.6+将过滤条件推送到存储引擎,减少回表次数。

索引选择性:高唯一性(如ID)的列更适合建索引,区分度低的列(如性别)效果差。