深入后端架构 · 解析核心技术
索引是 MySQL 性能优化的核心手段。理解索引的底层数据结构和工作原理,能帮助你设计出高效的数据库查询方案,避免常见的性能陷阱。
InnoDB 存储引擎默认使用 B+ 树作为索引的数据结构。与 B 树不同,B+ 树的所有数据都存储在叶子节点,且叶子节点之间通过双向链表相连,非常适合范围查询和排序操作。
-- 查看表的索引信息
SHOW INDEX FROM users;
-- 分析查询的执行计划
EXPLAIN SELECT * FROM users WHERE age > 25 ORDER BY created_at;
通过 EXPLAIN 可以清楚地看到查询是否命中了索引,以及扫描了多少行数据。
InnoDB 中,主键索引就是聚簇索引,叶子节点直接存储完整的行数据。二级索引(非主键索引)的叶子节点存储的是主键值,查询时需要"回表"操作来获取完整数据:
-- 聚簇索引查询,直接定位数据
SELECT * FROM users WHERE id = 1;
-- 二级索引查询,需要回表
SELECT * FROM users WHERE email = 'test@example.com';
-- 覆盖索引,无需回表
SELECT id, email FROM users WHERE email = 'test@example.com';
当查询的字段都包含在索引中时,就形成了覆盖索引,可以避免回表,大幅提升查询性能。
联合索引遵循最左前缀匹配原则。例如创建索引 INDEX(a, b, c),那么查询条件中必须包含字段 a 才能利用到这个索引:
-- 创建联合索引
ALTER TABLE orders ADD INDEX idx_user_status_time(user_id, status, created_at);
-- 能命中索引
SELECT * FROM orders WHERE user_id = 1;
SELECT * FROM orders WHERE user_id = 1 AND status = 'paid';
SELECT * FROM orders WHERE user_id = 1 AND status = 'paid' AND created_at > '2026-01-01';
-- 无法命中索引
SELECT * FROM orders WHERE status = 'paid';
SELECT * FROM orders WHERE created_at > '2026-01-01';
在实际使用中,有些写法会导致索引失效:对索引列使用函数或表达式运算、隐式类型转换、LIKE 以通配符开头、OR 条件中部分列无索引等。使用 EXPLAIN 定期检查慢查询,是发现索引问题的最有效手段。
在实际项目中,合理的索引策略至关重要:优先为 WHERE、JOIN、ORDER BY 涉及的高频字段创建索引;利用覆盖索引减少回表;控制单表索引数量避免写入性能下降;定期使用 pt-query-digest 分析慢查询日志,针对性地优化索引。
索引优化是后端开发的必备技能。从理解 B+ 树结构到掌握最左前缀匹配,再到实战中的慢查询分析,系统化的索引优化思路能帮助你构建高性能的数据库方案。