数据量太小的时候,别急着加索引
有个朋友在做个小项目,就一张用户表,总共不到一百条记录。他一上来就在 name 字段上建了个索引,说是为了查询更快。其实真没必要。这种数据量,全表扫一下也就几毫秒的事,加了索引反而多了一层维护开销。就像你家里只有三本书,还专门去买个书架分类,折腾。
频繁写入的表,索引可能拖后腿
比如日志系统,每秒成千上万条 insert 操作。如果给这些字段加了索引,每次插入都得同步更新索引树,磁盘 IO 直接拉高。我之前接手一个报警日志表,原本查得挺快,后来在时间戳和级别字段都加了索引,结果写入延迟翻倍。最后把非必要的索引删掉,写入性能立马回升。
像这种写多读少的场景,得掂量清楚:你是更怕写不进去,还是更怕查不出来?
区分度太低的字段,建了也白建
比如性别字段,就“男”和“女”两个值。即使建了索引,查 female 时还是要扫一半的数据。MySQL 优化器很可能直接忽略这个索引,强制走全表扫描。与其留着占地方,不如删了省点空间。
字符串字段过长,索引代价太高
有次看到有人在 description 文本字段上建了完整长度的索引,类型是 TEXT。这问题大了——InnoDB 单个索引列不能超过 767 字节,超了会报错。就算用前缀索引,比如取前 100 个字符,存储和维护成本也不低。更麻烦的是,前缀太短可能失效,太长又浪费,很难平衡。
如果真要查内容,倒不如用 Elasticsearch 这类工具,专门干这事。
组合索引顺序不当,等于没建
有张订单表,组合索引是 (status, create_time),这时候你要是按 create_time 单独查询,这个索引基本用不上。B+ 树的结构决定了它得从左往右匹配。就像电话簿先按姓氏再按名字排,你只记得名字是查不出来的。
正确的做法是根据查询条件调整顺序,或者拆出单独的索引,看实际访问模式。
临时表或中间表,别滥用索引
做数据清洗的时候,经常建些临时表存中间结果。有些人习惯性地给每个字段都加上索引,觉得“反正要查”。但这类表生命周期短,数据用完就删,索引根本来不及发挥作用,白白消耗创建时间和资源。
除非这个临时表会被反复关联查询,否则别折腾。
某些模糊查询,索引也会失效
比如这样一条语句:
SELECT * FROM users WHERE name LIKE '%张';哪怕 name 上有索引,这种前面带 % 的模糊匹配也没法用 B+ 树加速。索引只能支持 “张%” 这种前缀匹配。想查包含“张”的名字,这条路走不通。
遇到这种情况,与其硬扛,不如考虑全文索引或者其他搜索方案。