以为索引越多越好
很多人觉得,既然索引能加快查询,那就给每个字段都加上索引。比如一个用户表,id、name、email、phone、address 全部建上索引,查起来肯定快。可现实是,每多一个索引,写入数据时就要多维护一份结构。就像你家楼下开了五家快递柜,取件是快了,但送货员得一家一家放,反而更慢。
尤其是频繁插入或更新的表,索引太多会导致性能下降明显。实际应用中,应该根据查询频率和业务场景选择性地建立索引,而不是盲目堆数量。
忽略了最左前缀原则
复合索引(联合索引)是常用优化手段,比如对 (last_name, first_name) 建立联合索引。但有人发现,用 first_name 单独查询时索引失效了,就以为数据库“抽风”。
其实这是最左前缀规则在起作用。MySQL 的 B+树索引要求从左往右匹配,只有查询条件包含了索引的最左列,才能有效利用索引。比如:
CREATE INDEX idx_name ON users(last_name, first_name);这时候 WHERE last_name = '张' 能走索引,WHERE last_name = '张' AND first_name = '三' 也能走,但单独用 first_name 就不行。
在索引字段上做函数操作
有个订单表,想查某一天下的单,写成这样:
SELECT * FROM orders WHERE DATE(create_time) = '2024-03-15';看起来没问题,但 DATE() 函数作用在字段上,会导致索引失效。因为数据库无法直接比对 create_time 的原始值,只能全表扫描。
正确做法是改写成范围查询:
SELECT * FROM orders WHERE create_time >= '2024-03-15 00:00:00' AND create_time < '2024-03-16 00:00:00';这样即使 create_time 上有索引,也能正常使用。
误判唯一索引和普通索引的性能差距
有人听说唯一索引效率更高,就给所有主键外的字段也强行加唯一约束。其实对于查询来说,两者的读取性能差别微乎其微。真正区别在于写入时的校验成本——唯一索引需要额外检查冲突。
如果你的数据本身不唯一,硬加 UNIQUE 约束反而会让插入失败,增加业务处理复杂度。该用普通索引的时候别乱上唯一索引。
忽视了索引的选择性
选择性是指字段不同值的数量与总行数的比例。比例越高,索引效果越明显。比如性别字段只有“男”“女”,一万条数据里各占一半,这种字段建索引意义不大。
试想你在图书馆找书,如果按“是否借出”来分类,两个架子都堆满书,还是得一个个翻。但按“书名首字母”分,查找效率就高多了。所以低选择性的字段,比如状态位、类型码,通常不适合作为独立索引字段。
认为索引能解决所有慢查询
看到一条 SQL 慢,第一反应就是“加个索引试试”。但有些慢查询根本不是索引的事。比如关联查询没关联合适字段,或者子查询嵌套太深,又或者返回了大量不需要的字段。
还有种情况是索引存在,但统计信息过期,执行计划选错了。这时候光建索引没用,得 ANALYZE TABLE 更新统计信息,或者重写查询逻辑。
索引是利器,但不是万能钥匙。搞清楚问题根源,比盲目加索引更重要。