MySQL中并非所有字段都适合建索引,低选择性、频繁更新、超长文本及极少被查询使用的字段均不宜单独建索引,应依据查询模式、数据分布与更新频率综合判断。

MySQL 中并不是所有字段都适合建索引,盲目添加索引反而会拖慢写入性能、浪费存储空间,甚至让优化器选错执行计划。关键要看数据分布、查询模式和更新频率。
低选择性字段不适合建索引
选择性 = 不重复值数量 / 总行数。若该比值很低(如
- 性别字段(只有“男/女/未知”),索引几乎无效,全表扫描更快
- 状态字段(如 status IN (0,1,2)),除非配合高过滤条件(如 WHERE status=1 AND create_time > '2024-01-01'),否则单独建索引意义不大
- 可先用 SELECT COUNT(DISTINCT col)/COUNT(*) FROM table; 估算选择性
频繁更新的字段慎建索引
每次 INSERT/UPDATE/DELETE 都要同步维护索引树,写多读少的场景下,索引开销可能远超收益。
- 订单表中的 last_updated_at 字段,每秒更新数百次,单独为其建索引会显著增加写延迟
- 计数类字段(如 view_count、like_count)随用户行为高频变更,不宜单独索引
- 若必须加速某类更新后查询,优先考虑组合索引中将该字段放在末尾,而非独立索引
超长文本字段不适合直接建普通索引
TEXT、BLOB 类型不能直接创建完整长度的 B+ 树索引,且前缀索引效果不稳定。
-
content TEXT 字段建 FULLTEXT 索引仅适用于全文检索,不适用于
=或IN等精确匹配 - 对 URL、描述等字段建前缀索引(如 INDEX(url(100)))需验证实际区分度:前100字符是否足够唯一?可用 SELECT COUNT(DISTINCT LEFT(url,100)) = COUNT(*) FROM t; 检查
- 若业务只需模糊查找开头(如 LIKE 'https://example%'),前缀索引有效;但 LIKE '%example' 则完全用不上
极少被 WHERE / JOIN / ORDER BY 使用的字段没必要建索引
索引只在特定访问路径中生效。没有对应查询驱动,索引就是闲置资源。
- 日志表中的 raw_data JSON 字段,若从不用于查询条件或排序,无需生成生成列+索引
- 归档表中只做冷备、基本不查询的字段,建索引纯属浪费
- 可通过 performance_schema.table_io_waits_summary_by_index_usage(MySQL 8.0+)查看索引实际命中情况,定期清理未使用的索引
判断一个字段要不要建索引,核心是看它是否稳定出现在高频、高代价查询的驱动条件中,并具备足够区分度。不复杂但容易忽略。










