文章目录
- 索引分类
- 数据结构分类
- 物理存储分类
- 字段特性分类
- 字段个数分类
- 索引核心原理
- B+树结构
- 索引查询流程
- 关键概念解析
- 索引使用场景与优化
- 需要索引
- 无需索引
- 索引优化
- 索引失效
索引分类
索引是数据库系统中用于提高数据查询效率的核心结构。MySQL 尤其是 InnoDB 引擎中,索引的使用对性能影响巨大。本文将全面系统地介绍 MySQL 中的索引。
数据结构分类
B + 树索引:MySQL 里极为常用的索引类型。以 B + 树这种数据结构为依托,其所有数据均存储在叶子节点,且叶子节点通过链表有序相连,范围查询高效便捷。同时,B + 树的结构保证了数据的稳定性和查询性能的高效性,查找、插入、删除操作的时间复杂度均为 O (log n)。
Hash 索引:利用哈希表来存储索引键值对。其显著优势在于等值查询时速度极快,能在常数时间内定位数据。然而,它并不支持范围查询,且在数据频繁变动时,哈希冲突可能导致性能下降。
Full - Text 索引:专门用于文本搜索场景。当处理大量文本数据,如文章、评论等内容的模糊匹配查询时,Full - Text 索引能发挥强大作用,可快速定位包含特定关键词的文本记录。
物理存储分类
聚簇索引:聚簇索引决定了表中数据的物理存储顺序。在 InnoDB 存储引擎中,聚簇索引的叶子节点直接存储完整的数据行。通常,主键会自动成为聚簇索引。
非聚簇索引:非聚簇索引的叶子节点存储的是索引字段和主键值。在 InnoDB 中,除主键索引外的其他索引大多属于非聚簇索引。当通过非聚簇索引查询数据时,先找到主键值,再依据主键去聚簇索引中获取完整的数据行,这一过程被称为回表。
字段特性分类
主键索引:一种特殊的唯一索引,用于唯一标识表中的每一条记录。一个表只能有一个主键索引,它不允许出现 NULL 值。
唯一索引:保证索引字段的值具有唯一性,可包含多个 NULL 值(但 InnoDB 存储引擎中,对于唯一索引列,NULL 值被视为相同值,只能有一个)。
普通索引:最常见的索引类型,对字段值没有唯一性等特殊要求,主要用于加速查询操作。
字段个数分类
单列索引:基于单个字段创建的索引。
联合索引:由多个字段组合而成的索引。创建联合索引时需遵循最左匹配原则,即查询条件需从索引的最左侧字段开始匹配。
索引核心原理
B+树结构

B+树是MySQL索引的默认数据结构,具有以下特点:
-
多叉平衡树:保持数据平衡,查询效率稳定。
-
节点大小:通常设置为磁盘页大小(16KB),I/O友好。
-
结构组成:根节点:索引的起点;非叶子节点:只存储键值和指向子节点的指针;叶子节点:存储键值和数据(聚簇索引)或主键(非聚簇索引);叶子节点通过双向链表连接,便于范围查询。
-
优点:
- 磁盘 I/O 友好:B + 树的一个节点大小通常与磁盘页大小相同(如 16KB)。这使得单次 I/O 操作可加载大量键值,减少了磁盘访问次数。
- 范围查询高效:由于叶子节点通过链表连接,在进行范围查询时,只需定位到范围的起始和结束位置,然后顺序扫描链表即可遍历整个范围的数据,无需像二叉搜索树那样进行多次递归查找。
- 查询性能稳定:B + 树会通过页分裂和页合并的机制自动保持平衡。在插入或删除数据时,若导致节点数据过多或过少,会触发页分裂或页合并操作,避免树的高度增长过快,从而保证查找操作的时间复杂度始终稳定在 O (log n),确保了查询性能的稳定性。
索引查询流程

- 从根节点开始:通过二分查找确定数据所在区间。
- 逐层向下:沿着非叶子节点的指针找到对应的叶子节点。
- 定位数据:
- 聚簇索引:直接在叶子节点获取完整数据。
- 非聚簇索引:获取主键后需要"回表"查询。
关键概念解析
- 回表:使用非聚簇索引查询时,通过索引找到主键后,还需要根据主键去聚簇索引中读取完整数据行。
- 覆盖索引:查询的所有列都包含在索引中,无需回表。
- 索引下推:存储引擎层利用索引对WHERE条件进行部分过滤,减少回表次数。
索引使用场景与优化
需要索引
-
当字段具有唯一性限制时,建立索引可确保数据的唯一性校验高效进行,同时加速基于该字段的查询操作。
-
在
WHERE
条件中频繁出现的字段,建立索引能显著加快查询速度。 -
对于频繁使用
ORDER BY
或GROUP BY
的字段,索引可以帮助快速对数据进行排序或分组操作。
无需索引
- 数据量极小的表,由于数据量少,全表扫描的成本较低。
- 频繁更新的字段,每次更新操作都可能导致索引的调整和维护,增加系统开销。
- 存在高重复值的列,如性别列(只有 “男”“女” 两个值),索引的区分度较低,对查询性能提升有限。
- 长文本字段,如文章内容、详细描述等字段,由于其数据量较大,建立索引会占用大量存储空间,且查询效率提升不明显,一般不适合建立普通索引,但可考虑使用 Full - Text 索引用于文本搜索。
索引优化
- 主键索引设置:主键索引最好采用自增方式。因为自增主键在插入数据时,数据会顺序插入到聚簇索引的末尾,避免了页分裂造成的数据迁移。若主键值随机,可能会频繁导致页分裂,影响插入性能和索引结构的稳定性。
- 索引字段设置为 NOT NULL:将索引字段设置为 NOT NULL,一方面可增加优化器的优化难度,另一方面能避免占用行空间来存储数据是否为空的标识,提高存储效率。
- 前缀索引优化:对于较长的字符串字段,可使用前缀索引优化。即使用较长字符串的前几个字符作为索引,既能减少索引存储空间,又能在一定程度上提高查询效率。
- 优化覆盖索引:通过建立联合索引,使查询所需的所有列都包含在索引中,避免回表的 I/O 性能损耗。
索引失效
- 当使用
LIKE
模糊匹配时,若匹配模式为 “% xx” 或 “% xx%”,索引将失效。因为这种情况下无法利用索引的有序性进行快速查找,只能进行全表扫描。 - 对索引字段进行运算、使用函数或类型转换操作,会导致索引失效。
- 在
WHERE
语句中使用OR
连接条件时,若OR
前是索引字段,OR
后不是索引字段,索引会失效。 - 对于联合索引,若未遵循最左匹配原则,索引会失效。