Skip to content

哪些字段适合加索引,哪些不适合

1. 索引的收益与成本

索引的本质是“用额外空间换查询效率”。是否要建索引,本质上是在权衡:

  • 收益:减少扫描行数、减少排序/回表、加速 JOIN。
  • 成本:写入更慢(维护 B+ 树)、占用更多磁盘与 Buffer Pool、可能带来更多锁竞争与页分裂。

因此,“适合建索引”通常意味着:这个字段能显著降低读取成本,并且写入维护成本可接受

2. 适合加索引的字段

2.1 过滤条件与连接条件

高频出现在以下位置的字段,优先考虑索引:

  • WHERE:等值、范围过滤。
  • JOIN ON:关联键(尤其是大表关联)。
  • ORDER BY / GROUP BY:如果能利用索引有序性,可避免额外排序/临时表。

2.2 区分度高(高选择性)

区分度高的列(例如用户 ID、订单号)能显著减少扫描行数,索引收益更大。反之,取值很少的列(性别、状态位)单列索引往往收益有限。

2.3 覆盖索引需要的组合列

如果查询只涉及索引中的列,InnoDB 可以直接从二级索引返回结果,减少“回表”。因此常见做法是为高频查询建联合索引以覆盖查询字段。

3. 不适合加索引的字段

3.1 低区分度字段(单列)

例如性别、布尔标志、少量枚举值。优化器可能仍会选择全表扫描,因为走索引 + 回表的代价未必更低。

3.2 高频更新字段

更新索引列会触发索引维护,可能导致页分裂与更多 I/O。写压力大时,索引过多会明显拖慢写入吞吐。

3.3 超长字段与很少被查询的字段

例如大文本、JSON 大字段。若必须基于前缀查询,可以考虑:

  • MySQL 的前缀索引(Prefix Index)(需评估区分度)。
  • 生成列(Generated Column)+ 索引(把表达式结果落地成列)。
  • 专用检索系统(如全文检索)替代在关系库里硬做。

4. 联合索引设计要点

4.1 左前缀与“等值在前,范围在后”

联合索引((a, b, c))能支持 a=?a=? AND b=?a=? AND b BETWEEN ... 等,但通常不支持跳过前导列直接用 b=?

一般经验:

  • 等值条件列放在前面,范围条件列放在后面。
  • 如果还要 ORDER BY,要结合排序字段来排索引顺序,尽量利用索引顺序避免 filesort。

4.2 用执行计划验证

索引是否生效不要凭感觉,应该用 EXPLAIN / EXPLAIN ANALYZE 观察:

EXPLAIN SELECT * FROM t WHERE a = 1 AND b = 2 ORDER BY c;

重点关注:typekeyrowsExtra(是否 Using index / Using filesort / Using temporary)。