mysql哪些情况不适合建索引_mysql索引使用场景分析

10次阅读

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

mysql哪些情况不适合建索引_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+)查看索引实际命中情况,定期清理未使用的索引

判断一个字段要不要建索引,核心是看它是否稳定出现在高频、高代价查询的驱动条件中,并具备足够区分度。不复杂但容易忽略。

text=ZqhQzanResources