MySQL 索引优化完全指南:B+树原理与实战
索引是 MySQL 性能优化的核心。本文深入介绍索引的原理和优化方法。
B+树结构
[10 | 20]
/ | \
[1|5] [12|15] [22|25]
- 非叶子节点只存储索引
- 叶子节点存储数据,且互相链接
- 所有查询都走到叶子节点
索引类型
主键索引
CREATE TABLE users (
id BIGINT PRIMARY KEY,
name VARCHAR(100)
);
唯一索引
CREATE UNIQUE INDEX idx_email ON users(email);
普通索引
CREATE INDEX idx_name ON users(name);
联合索引
CREATE INDEX idx_name_age ON users(name, age);
联合索引最左前缀
-- 索引:(name, age, city)
-- ✅ 能用索引
WHERE name = '张三'
WHERE name = '张三' AND age = 25
WHERE name = '张三' AND age = 25 AND city = '北京'
-- ❌ 不能用索引
WHERE age = 25
WHERE city = '北京'
WHERE age = 25 AND city = '北京'
覆盖索引
查询的字段都在索引中,无需回表。
-- 索引:(name, age)
-- 覆盖索引(不用回表)
SELECT name, age FROM users WHERE name = '张三';
-- 需要回表
SELECT name, age, email FROM users WHERE name = '张三';
EXPLAIN 分析
EXPLAIN SELECT * FROM users WHERE name = '张三';
| 字段 | 说明 |
|---|---|
| type | 访问类型(ALL/index/range/ref/const) |
| key | 使用的索引 |
| rows | 扫描行数 |
| Extra | 额外信息 |
索引优化建议
- 选择区分度高的列:区分度 = 不重复值 / 总行数
- 避免函数操作:WHERE YEAR(create_time) = 2024 无法用索引
- 避免类型转换:字符串不加引号会导致索引失效
- 联合索引顺序:区分度高的列放前面
总结
索引是 MySQL 性能优化的核心。理解 B+树原理,合理创建索引,可以大幅提升查询性能。