文章目录
-
- 一、高频出现在 WHERE 条件中的字段
-
- 为什么适合
- 典型例子
- 重要补充
- 二、JOIN 关联查询中的关联字段(外键字段)
-
- 为什么适合
- 典型例子
- 注意
- 三、ORDER BY / GROUP BY 后面的字段
-
- 为什么适合
- 典型例子
- 补充技巧
- 四、区分度高的字段(Cardinality 大)
-
- 为什么适合
- 判断标准
- 对应你的表
- 五、需要保证唯一性的业务字段
-
- 为什么适合
- 典型例子
- 六、适合做「覆盖索引」的高频查询
-
- 为什么适合
- 典型例子
- 反向补充:这些情况不建议建索引
- 新手建索引优先级参考
一、高频出现在 WHERE 条件中的字段
这是索引最核心、最常用的场景。
为什么适合
查询时,如果字段没有索引,就必须逐行扫描整张表(全表扫描); 有了索引,就能通过 B+ 树快速定位到符合条件的行,数据量越大提速越明显。
典型例子
- 业务中经常按「员工姓名」「邮箱」「部门ID」查员工信息,这些字段就适合建索引。
- 对应你的 employees 表:department_id、job_id 这类经常作为筛选条件的字段,建索引就是合理的。
重要补充
如果多个字段经常组合在一起做查询条件,优先建联合索引,而不是给每个字段单独建单列索引。 比如,经常用 name + age 筛选,建 idx_name_age(name, age) 的收益,远高于两个单列索引。
二、JOIN 关联查询中的关联字段(外键字段)
联表查询的关联字段,几乎是必建索引的场景。
为什么适合
两张表关联查询时 (比如 employees JOIN departments ON employees.department_id = departments.id), 如果关联字段没有索引,每次关联匹配都要做一次全表扫描,数据量上来后性能会极差。
典型例子
你的 employees 表里的 department_id、job_id、manager_id 都属于这类:
- department_id 关联部门表
- job_id 关联职位表
- manager_id 关联上级员工(自连接)
这也是为什么你这张表的这三个字段都已经建了索引,是非常标准的建法。
注意
关联字段的类型、长度、字符集必须完全一致,否则会触发隐式类型转换,导致索引失效。
三、ORDER BY / GROUP BY 后面的字段
排序 和 分组,是索引的第二大适用场景。
为什么适合
B+ 树索引本身就是排好序的结构:
- ORDER BY:直接用索引的顺序输出,不用再做「文件排序(Using filesort)」,速度提升非常明显
- GROUP BY:索引有序,分组时不用再生成临时表(Using temporary),避免额外的内存/磁盘开销
典型例子
- 经常按「入职时间倒序」查询员工列表 → hire_date 适合建索引
- 经常按「部门分组统计人数」 → department_id 适合建索引
补充技巧
如果查询同时有 WHERE 和 ORDER BY,优先建联合索引,把 WHERE 字段放最左边,排序字段放后面,符合最左前缀原则,既能过滤又能排序。 比如:WHERE department_id = 10 ORDER BY hire_date 建 idx_dept_hire(department_id, hire_date)
四、区分度高的字段(Cardinality 大)
索引的效率,很大程度取决于字段的「区分度」。
为什么适合
区分度越高,索引一次能过滤掉的数据就越多,查询效率提升越明显; 反之,如果字段值大量重复,索引过滤不了几行,优化器会觉得还不如全表扫,直接放弃索引。
判断标准
看 SHOW INDEX 里的 Cardinality 值,值越接近表总行数,区分度越好。
- ✅ 适合:邮箱、工号、身份证号,几乎不重复,区分度拉满
- ❌ 不适合:性别、状态(只有 0/1 两种值)、是否删除等低基数字段
对应你的表
- employee_id、email 基数 107,和表总行数一致 → 区分度极好,建索引收益最高
- department_id 基数 12 → 区分度一般,数据量小的时候还行,百万级数据下收益会很低
五、需要保证唯一性的业务字段
业务上要求不重复的字段,直接建唯一索引,一举两得。
为什么适合
典型例子
- 员工邮箱、工号、身份证号
- 对应你表里的 emp_email_uk,就是非常标准的唯一索引设计
六、适合做「覆盖索引」的高频查询
这是进阶优化场景,用得好性能提升非常显著。
为什么适合
如果一条查询要取的字段,在索引里就全部包含了,就不需要回表去聚簇索引里查完整数据,直接从二级索引里就能拿到结果,这就是覆盖索引,省去了回表的IO开销。
典型例子
业务高频执行:
SELECT name, age
FROM employees
WHERE name = '张三';
建联合索引 idx_name_age(name, age),查询时直接从索引里取 name 和 age,完全不用回表, 性能接近主键查询。
反向补充:这些情况不建议建索引
知道什么时候建,也要知道什么时候别乱建:
新手建索引优先级参考
按重要性从高到低:



