索引设计速查:哪些字段该建索引?哪些不能建?
在数据库优化中,索引(Index) 是提升查询性能的“利器”,但也是一把“双刃剑”。
建得好,查询飞快;建得多,性能反而下降。
很多开发者在写 SQL 时,只知道“加索引能快”,却忽视了——并不是所有字段都该建索引!
这篇文章带你从实战角度快速掌握:
✅ 哪些字段适合建索引
🚫 哪些字段千万别建索引
🎯 如何在面试中解释“索引设计的合理性”
一、索引设计的核心原则
索引不是越多越好,它的作用是加快“查”,但会拖慢“增删改”。
简单理解:
“查询快”的代价,是“写入慢”。
所以建索引前,必须明确——
👉 这个字段是否经常出现在 WHERE、JOIN、ORDER BY、GROUP BY 等语句中?
👉 查询性能提升是否值得增加维护开销?
只有真正能帮助定位数据的字段,才值得建索引。
二、哪些字段该建索引?
1. 作为查询条件的字段(WHERE 条件)
如果某字段在查询条件中经常被使用,它是最值得建索引的。
例如:
SELECT * FROM user WHERE phone = '13800138000';
phone 字段经常用于查找用户信息,那么在 phone 上建立索引,可以显著加快查询速度。
2. 作为排序条件的字段(ORDER BY)
当查询结果需要排序时,索引可以避免数据库执行“文件排序”。
例如:
SELECT * FROM orders ORDER BY create_time DESC;
在 create_time 上建立索引,可减少排序的性能损耗。
3. 作为分组条件的字段(GROUP BY)
GROUP BY 语句常用于聚合分析,若分组字段被索引覆盖,可以提升聚合效率。
例如:
SELECT category, COUNT(*) FROM products GROUP BY category;
此时对 category 建索引,会加快分组计算。
4. 作为表连接条件的字段(JOIN)
多表查询中,连接条件字段非常关键。
若两表通过某字段关联,建议双方都在该字段上建索引。
例如:
SELECT *
FROM orders o
JOIN user u ON o.user_id = u.id;
user_id 与 id 都应建立索引,以避免连接时的全表扫描。
5. 具有高区分度的字段
字段的“区分度”越高,索引效果越好。
区分度指:字段中不同值的比例。
例如:
用户手机号、身份证号、邮箱 → 区分度高,建索引效果佳。
性别、状态(如0/1) → 区分度低,建索引意义不大。
简单判断:
字段值重复率高(如只有几种状态) → 不适合建索引。
字段值唯一或接近唯一 → 优先考虑建索引。
6. 复合索引中的常用组合字段
如果查询经常涉及多个条件,可以考虑创建复合索引(联合索引)。
例如:
SELECT * FROM orders WHERE user_id = 1 AND status = 'PAID';
此时 (user_id, status) 作为复合索引,可以一次性满足两个查询条件。
记得遵守“最左前缀原则”,即查询条件要包含索引最左的字段。
三、哪些字段不建议建索引?
1. 经常被修改的字段
索引在更新时会同步维护索引树结构。
如果某字段频繁更新,会造成索引页频繁重排,导致写入性能下降。
例如:
登录次数、余额、库存数量等字段,不建议建索引。
2. 字段值重复率极高
如果一个字段的取值非常有限,比如性别(男女)、状态(0/1),索引几乎不会提升查询速度。
原因是:
数据库依然需要扫描大量数据行才能找到目标结果。
3. 字段长度过长(如大文本)
在 TEXT、BLOB、VARCHAR(1000+) 这类长字段上建索引,会占用大量存储空间。
不仅索引文件庞大,还会降低缓存命中率。
解决方式:
可以使用前缀索引:
CREATE INDEX idx_email_prefix ON user(email(10));
只索引前 10 个字符,兼顾性能与存储。
4. 临时字段或中间结果字段
有些字段只是中间计算结果、缓存数据、临时存储,不参与查询逻辑。
这类字段建索引纯属浪费。
5. 数据量很小的表
如果表只有几百行数据,全表扫描的成本非常低,索引反而是“画蛇添足”。
MySQL 优化器在判断时甚至会忽略索引,直接顺序扫描更快。
四、面试高频问题解析
1. 为什么性别字段不适合建索引?
因为字段区分度太低(只有男女两种值),即使建索引,查询时仍要扫描大量记录。
2. 索引为什么会影响写入性能?
插入、更新、删除数据时,数据库要同时维护索引结构(如 B+Tree),造成额外的写入开销。
3. 如何判断一个字段是否适合建索引?
可以根据“查询频率 + 字段区分度 + 修改频率”三要素综合评估。
4. 复合索引的最左前缀原则是什么?
联合索引只有从左到右的字段顺序连续匹配时才能被使用。例如 (a, b, c) 索引可用于 WHERE a=1 AND b=2,但不能只用 WHERE b=2。
五、总结与设计建议
在实际开发中,索引设计是一项平衡艺术。
记住这三条黄金法则:
建在查得多的字段上,不建在改得多的字段上。
索引要少而精,不求多而全。
定期用 EXPLAIN 检查查询执行计划,优化无效索引。
一句话总结:
“索引不是万能的,但没有索引,数据库万万不能。”