一、MySQL进阶
1. 索引
索引设计不是简单地给每个字段加个索引,而是一场在查询性能 、写入速度 、存储空间 和维护成本之间的精细权衡。
1.1 设计原则
1. 索引不是越多越好,而是越精准越好
核心理念
索引虽好,但有代价:
- 写入性能下降:每次INSERT/UPDATE/DELETE都需要同步更新所有相关索引
- 存储空间膨胀:每个索引都是一棵B+树,占用额外磁盘空间
- 优化器负担加重:索引越多,MySQL查询优化器选择执行计划的时间越长
数据说话:一张1亿行的用户表,若建立10个二级索引,写入速度可能下降30%~50%,存储空间翻倍。
sql
-- 错误示范:为低频查询字段建立索引
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id BIGINT,
created_at DATETIME,
internal_remark TEXT -- 业务字段,但只在后台统计时偶尔查询
);
CREATE INDEX idx_internal_remark ON orders(internal_remark); -- ❌ 低频查询,浪费索引
-- 正确做法:针对高频查询字段建立索引
CREATE INDEX idx_user_created ON orders(user_id, created_at); -- ✅ 高频查询条件
2. 表级别:何时建立索引?
核心原则
索引的收益与表的数据量和查询频率成正比:
- 数据量越大,索引的价值越明显
- 查询越频繁,索引的回报越高
选择标准
| 表类型 | 数据量 | 查询频率 | 是否建索引 | 说明 |
|---|---|---|---|---|
| 配置表 | <100行 | 高频 | ❌ 不建 | 全表扫描成本低 |
| 字典表 | 500行 | 高频 | ✅ 建索引 | 每秒查询100次值得建 |
| 订单表 | 1000万行 | 高频 | ✅ 建索引 | 索引价值高 |
| 订单表 | 1000万行 | 低频 | ❌ 不建 | 维护成本高 |
经验值 :一般表数据量超过1000行,才考虑建立索引。但需结合查询频率,如500行表每秒查询100次,也值得建索引。
经验值 :一般表数据量超过1000行,才考虑建立索引。但需结合查询频率,如500行表每秒查询100次,也值得建索引。
3. 字段级别:哪些字段适合建索引?
三大应用场景
索引主要适用于以下三大场景:
- 过滤(WHERE条件) :如
WHERE user_id = 123 - 排序(ORDER BY) :如
ORDER BY create_time DESC - 分组(GROUP BY) :如
GROUP BY category_id
高选择性字段优先
选择性 = COUNT(DISTINCT column_name) / COUNT(*)
| 字段 | 选择性 | 是否适合建索引 | 说明 |
|---|---|---|---|
| user_id | 0.98 | ✅ | 高选择性,几乎唯一 |
| gender | 0.02 | ❌ | 低选择性,只有两个值 |
| status | 0.35 | ✅ | 选择性>0.32,适合建索引 |
| city | 0.15 | ❌ | 选择性<0.2,效果不佳 |
最佳实践:优先为高选择性的列创建索引,或将其作为联合索引的首列。


