必须加索引的字段包括WHERE、JOIN、ORDER BY、GROUP BY中高频出现的字段;主键自动索引,外键参与JOIN时两端均需索引;高区分度字段宜建唯一索引;联合索引须遵循最左前缀原则。

哪些字段必须加索引?
WHERE、JOIN、ORDER BY、GROUP BY 中高频出现的字段,基本都要建索引。比如 user_id 在 WHERE 中频繁过滤,order_status 和 created_at 一起用于分页查询,那就该优先考虑联合索引。
主键字段自动带主键索引,不用额外操作;外键字段如果参与 JOIN,两边都得加索引,否则 JOIN 会变慢甚至走全表扫描。
- 区分度高的字段(如手机号、订单号)适合建唯一索引
UNIQUE - 小表(
- 性别、状态(0/1)、删除标记(is_deleted)这类低区分度字段,加了也几乎不生效
联合索引怎么写才有效?
关键看查询条件是否满足「最左前缀原则」。例如建了 INDEX idx_name_age_city (name, age, city),只有以下写法能命中:
WHERE name = '张三'-
WHERE name = '张三' AND age > 25(等值在前,范围在后) WHERE name = '张三' AND age = 25 AND city = '北京'
这些写法完全无效:
-
WHERE age = 25(跳过最左列name) -
WHERE city = '北京'(没用到最左列) -
WHERE age = 25 AND city = '北京'(name缺失,后面全失效)
记住:等值条件放前面,范围条件(BETWEEN、>、)放最后,高区分度字段靠左。
什么时候索引会悄悄失效?
不是建了就一定用得上。常见失效场景包括:
- 对索引列做运算:
WHERE age + 1 = 30→ 改成WHERE age = 29 - LIKE 前置模糊:
WHERE name LIKE '%明'→ 没法走索引;WHERE name LIKE '王%'可以 - 隐式类型转换:
WHERE mobile = 13812345678(字段是VARCHAR,传入数字)→ MySQL 自动转类型,索引失效 - 使用函数:
WHERE UPPER(name) = 'LISA'→ 改用函数索引(MySQL 8.0+)或提前规范存储格式
查不确定时,直接跑 EXPLAIN SELECT ... 看 key 和 type 列,key 为空或 type 是 ALL 就说明没走索引。
大表加索引要小心锁表
MySQL 5.6 之前,ALTER TABLE ADD INDEX 会锁整张表,业务高峰期绝对不能干。现在虽支持在线 DDL(ALGORITHM=INPLACE),但仍有风险:
- 数据量超 500 万行,建议在低峰期执行,同时监控磁盘 IO 和复制延迟
- 避免在从库上直接加索引,可能触发复制中断;优先在主库加,让从库自动同步
- 加完索引立刻
ANALYZE TABLE table_name,更新统计信息,防止优化器选错执行计划
真正麻烦的是那种凌晨三点还在跑的长事务——它会让 DDL 等待,进而阻塞后续所有写操作。上线前务必确认没有长事务挂着。


















