索引
基础教学 1 min read

索引

Blog Author

数据库索引:教学、使用场景与最佳实践指南


索引的本质与作用

**索引(Index)**是关系型数据库中用于提升查询性能的核心机制,作用等同于一本书的目录 —— 可以快速定位目标信息的位置。

  • 没有索引时: 查询需逐行扫描表,效率低下(尤其在百万级或更大数据规模下)。
  • 有索引时: 查询可通过索引结构(如 B+ 树)直接定位数据,I/O 成本显著减少。

🔍 索引是空间换时间的经典案例:它额外占用存储空间,但大幅减少查询时间。


常见索引类型(以 MySQL InnoDB 为例)

1. B+ 树索引(最常用)

  • 存储结构:根节点 + 中间节点 + 叶子节点
  • 所有数据均保存在叶子节点,有序,便于范围查询和二分查找
  • 每次查找平均只需 3\~4 次磁盘 I/O,适用于绝大多数查询场景

2. 全文索引

  • 适合模糊文本搜索,如博客、新闻内容字段(MyISAM 支持更早,InnoDB 需 5.6+)

3. R 树索引

  • 用于地理空间数据(GIS 数据),如地图坐标查找

本文聚焦于 B+ 树索引 —— 实际使用中最常见、最具代表性的索引类型。


InnoDB 索引结构与术语理解

1. 聚集索引(Clustered Index)

  • 每张表有且只有一个,即主键索引
  • 表数据直接存储在 B+ 树的叶子节点中,叶子节点即为整行数据

2. 非聚集索引(Secondary Index)

  • 用户手动创建的普通索引
  • 叶子节点只存储主键值 + 索引列
  • 查询时需通过主键回表获取完整行数据(称为回表查询

索引使用场景实操讲解

示例:查询学生姓名为“林震南”的记录

无索引时的执行计划:

EXPLAIN SELECT * FROM tb_student WHERE stuname='林震南'\G

输出显示 type: ALL(全表扫描),查询慢且低效。

创建索引:

CREATE INDEX idx_student_name ON tb_student(stuname);

再次执行 SQL:

EXPLAIN SELECT * FROM tb_student WHERE stuname='林震南'\G

此时 type: ref,扫描行数为 1,查询效率显著提升。

使用前缀索引:

CREATE INDEX idx_student_name_1 ON tb_student(stuname(1));

此索引仅使用“姓”进行索引,扫描行数增加至 2(因为两个姓“林”的学生),牺牲部分查询精度以节省空间。


使用 EXPLAIN 解读 SQL 性能

EXPLAIN 是分析 SQL 性能的核心工具。

字段名 含义
id 查询步骤 ID
select_type 查询类型(如 SIMPLE、PRIMARY)
table 当前查询的表名
type 访问类型,性能从好到差为:const > eq_ref > ref > range > index > ALL
possible_keys 可能使用的索引
key 实际使用的索引
rows 预计扫描的行数
Extra 额外信息,如是否使用了临时表、排序

索引删除方式

两种方式均可删除已存在索引:

ALTER TABLE tb_student DROP INDEX idx_student_name;
-- 或
DROP INDEX idx_student_name ON tb_student;

索引优化的高级用法

1. 复合索引(联合索引)

  • 例:CREATE INDEX idx_name_age ON tb_student(name, age);
  • 遵循最左前缀原则,可用于 (name)(name, age) 的查询,不能用于只查 age

2. 索引覆盖

  • 当查询所用字段都包含在索引中,不需要回表
  • 示例:只查询索引字段 nameage,不涉及其他列

3. 函数索引(MySQL 5.7+ 支持)

  • 如:CREATE INDEX idx_lower_name ON tb_student ((LOWER(name)));
  • 注意:索引中用到的表达式必须和查询语句保持一致

最佳实践与设计原则

✅ 应该索引的情况

  • WHERE 子句中频繁使用的字段
  • JOIN 条件的字段
  • ORDER BY 或 GROUP BY 中使用的字段
  • 高基数字段(值分布广,不重复)

❌ 不适合索引的情况

  • 表数据量小,查询快,建索引反而浪费
  • 经常变动的列(UPDATE/INSERT 频繁)
  • 重复值多的字段(如性别、状态等)

📌 总结设计原则

  1. WHERE 子句、JOIN 子句优先考虑加索引
  2. 基数越大,索引效率越高
  3. 前缀索引节省空间但降低精度
  4. 索引数量不宜过多,写操作成本增加
  5. 主键字段宜使用短类型(如 INT)
  6. 避免在索引列使用函数、LIKE '%xxx%' 模糊查询会导致索引失效

索引失效的常见原因

场景 说明
使用 LIKE '%前缀%' 索引失效,全表扫描
索引列参与计算 WHERE age + 1 = 20
数据类型不匹配 字符串用引号,数字不加引号
OR 连接的多个条件中有未加索引的字段 整体无法使用索引

结语:学会用好索引,是数据库性能优化的核心能力

索引设计是一门艺术,涉及性能、空间、维护成本的权衡。作为开发者,应掌握索引的类型、机制、优化方法,并善于使用 EXPLAIN 工具进行调优。熟练掌握这些技巧,将极大提高数据库应用的响应速度与可扩展性。

💡 记住:索引能救命,也可能拖垮系统。设计之前,请三思!

Related Topics