你是不是也遇到过:明明表里数据才几万条,查一条记录却要等好几秒?或者加了索引,查询反而更慢了?别急,这多半不是MySQL不行,而是索引没用对。
一、别啥字段都建索引
索引不是越多越好。比如一张用户表,给「昵称」「个性签名」「备注」全加上索引,看着挺全,其实浪费空间还拖慢插入速度。MySQL每多一个索引,插入、更新、删除都要多维护一份B+树。日常用得少的字段,真没必要加索引。
二、联合索引注意顺序
假设经常按「城市 + 年龄 + 性别」查用户,建联合索引时得写成 INDEX idx_city_age_sex (city, age, gender),不能反过来。因为索引是按最左前缀生效的——用到 WHERE city = '北京' 可以走索引;加了 AND age > 25 也能用上;但只查 gender = '女' 就完全用不上。
三、避免在索引列上做计算或函数
下面这种写法,哪怕name字段有索引,也白搭:
SELECT * FROM users WHERE UPPER(name) = 'LISA';改成 WHERE name = 'lisa'(前提是你存的就是小写),或者直接建函数索引(MySQL 8.0+):
CREATE INDEX idx_name_upper ON users ((UPPER(name)));四、别盲目用 LIKE '%关键词'
WHERE title LIKE '%教程' 这种后缀模糊查,索引基本失效。如果真要高频搜后缀,可以考虑倒序存字段再建索引,比如新增 title_reversed 字段存 '程教%',然后查 WHERE title_reversed LIKE '程教%',就能走索引了。
五、定期看看执行计划
写完SQL,别光测结果对不对,顺手加个 EXPLAIN:
EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND status = 'paid';重点盯 type 列(最好是 ref 或 const),还有 key 是否用了预期的索引,rows 是不是远小于总行数。如果显示 ALL,说明正在全表扫描,该优化了。
调索引不是一锤子买卖。上线后多观察慢查询日志,结合业务真实场景一点点试,比死背理论管用得多。