索引是数据库查询性能的核心。理解其不同分类,有助于我们在设计表结构和编写查询语句时做出正确决策,避免性能“翻车”。本文将从 数据结构、物理存储、字段特性 和 字段个数 四个维度,系统解析 MySQL 索引的分类与实战应用。
按数据结构分类
索引的本质是帮助数据库高效查找数据的数据结构。不同的数据结构决定了其查询效率和适用场景。这里有一个关键前提:不同存储引擎对索引类型的支持有差异。
- InnoDB引擎(MySQL 5.5后默认引擎):支持 B+Tree 索引;不支持手动创建 HASH 索引(但内存中会为高频查询自动生成“自适应HASH索引”);MySQL 5.6后支持 Full-Text 索引。
- MyISAM引擎(旧版常用):支持 B+Tree 索引和 Full-Text 索引,不支持 HASH 索引。
- Memory引擎(内存存储):支持 B+Tree 索引和 HASH 索引,不支持 Full-Text 索引。
鉴于 InnoDB 是当前绝对主流,B+Tree 索引是我们需要重点掌握的类型。
1. B+Tree索引:MySQL的“主力索引”
所有主流存储引擎都支持,也是 MySQL 默认创建的索引类型(如主键索引、普通索引的底层结构)。其核心优势是有序、支持范围查询、支持高效分页。底层是一棵平衡树,叶子节点存储数据(或主键值),非叶子节点存储索引值,查询效率稳定,适用于绝大多数业务场景。
2. HASH索引:适合“精准匹配”
底层基于哈希表实现,等值查询速度极快。但其缺点明显:不支持范围查询、不支持排序、不支持模糊查询。因此适用场景非常有限,仅适合“只做等值查询”的场景(如通过用户ID精准查询)。
注意:InnoDB 的“自适应HASH索引”由数据库自动管理,无法手动创建或控制。
3. Full-Text索引:全文检索“专用索引”
专门用于全文检索,例如查询文章内容中包含特定关键词的记录。相比 LIKE ‘%关键词%’(会导致索引失效),全文索引效率高得多。它通常用于 CHAR、VARCHAR、TEXT 等文本类型字段。
按物理存储分类
从物理存储角度看,索引主要分为两种。理解它们的区别,是掌握“回表查询”和“覆盖索引”等 数据库优化 概念的关键。
1. 聚簇索引(主键索引):“索引即数据”
聚簇索引是 InnoDB 引擎的核心特性(MyISAM 没有),其核心特点是:B+Tree 的叶子节点直接存放完整的用户数据行。
可以将其理解为一本书的“目录+正文”,目录页码直接对应正文内容。
一张表只能有一个聚簇索引。如果未定义主键,InnoDB 会选择第一个非空唯一列,或自动生成一个隐藏的 row_id 作为聚簇索引。
2. 二级索引(辅助索引):“索引指向数据”
除了聚簇索引外的所有索引(如普通索引、唯一索引、联合索引)都是二级索引。其核心特点是:B+Tree 的叶子节点存放的是主键值。
它像一本书的“子目录”,条目指向主目录的页码(主键值),需要二次查找才能获得完整数据。
由此衍生出两个直接影响性能的查询场景:
- 覆盖索引(高效):如果查询的字段全部包含在某个二级索引的叶子节点中(即索引字段或主键),则无需回表,直接返回结果,效率极高。
- 回表查询(低效):如果查询字段不在二级索引中,则需要先通过二级索引找到主键,再用主键去聚簇索引中取出完整数据行。多了一次索引查找,效率较低。
开发中应尽量设计查询使其能使用覆盖索引,避免回表。
按字段特性分类
根据字段的约束条件,索引可分为以下四种。
1. 主键索引:表的“唯一标识”
建立于主键字段上,核心作用是唯一标识一条记录。
- 一张表最多一个。
- 索引列值不允许为
NULL,且必须唯一。
- 在 InnoDB 中,主键索引就是聚簇索引。
2. 唯一索引:“字段值唯一,允许为空”
建立于 UNIQUE 约束字段上,核心作用是保证字段值的唯一性。
- 一张表可以有多个。
- 索引列值必须唯一,但允许为
NULL(可以有多个 NULL)。
- 在 InnoDB 中属于二级索引。
3. 普通索引:“最常用,无约束”
建立于普通字段上,无任何额外约束,核心作用是提升查询效率。是最常用的索引类型。
注意:索引虽能加速查询,但会降低增删改的效率(需维护索引),不宜滥用。
4. 前缀索引:“节省空间,提升效率”
一种特殊的普通索引,仅对字符类型字段的前 N 个字符建立索引。核心目的是在保证一定区分度的前提下,减少索引存储空间。
前缀长度 N 的选择至关重要:太短则区分度不足,太长则失去节省空间的意义。通常建议选择能使区分度达到 80% 以上的最短前缀(可通过 COUNT(DISTINCT LEFT(column_name, N)) / COUNT(*) 计算)。
按字段个数分类
根据索引关联的字段数量,可分为单列索引和联合索引。
1. 单列索引:“单个字段,简单直接”
建立在单个字段上的索引。优势是简单易维护,适合仅按该字段查询的场景。劣势是无法优化多字段联合查询。
2. 联合索引(复合索引):“多字段协同,优化联合查询”
建立在多个字段上的索引(如 INDEX(a, b, c)),核心作用是优化多字段联合查询。
其使用必须遵循 最左匹配原则:查询条件必须从索引的最左列开始,并向右连续匹配,否则索引可能失效。
以联合索引 (a, b, c) 为例:
- 生效:
WHERE a=1(用a)、WHERE a=1 AND b=2(用a,b)、WHERE a=1 AND b=2 AND c=3(全用)。
- 失效:
WHERE b=2(未从a开始)、WHERE b=2 AND c=3(未从a开始)。
- 部分生效:
WHERE a=1 AND c=3(仅a列生效,c列不生效)。
优化技巧:创建联合索引时,应将查询频率最高、区分度最高的字段放在最左边。
总结
索引是数据库性能的基石,但并非越多越好。核心在于深入理解其分类与原理,并结合实际的业务查询模式进行设计。无论是 B+Tree 的稳定高效,还是联合索引的最左匹配,或是避免回表的覆盖索引,其目标都是为了让查询更快、更省资源。掌握这些分类,你就能在表结构设计和 SQL 调优时更有章法,有效提升系统性能。