索引列顺序至关重要,因联合索引是按定义顺序整体排序的B+树,须遵循最左前缀原则;查询必须从最左列连续匹配,否则索引失效;首列应优先满足高频等值查询,范围查询宜靠右;首列选择性影响统计准确性与执行计划;排序/分组也严格依赖索引列顺序。

索引列顺序之所以重要,核心在于数据库如何组织和使用索引——尤其是联合索引,它不是多个单列索引的简单叠加,而是一棵按定义顺序整体排序的B+树。顺序不对,索引可能完全失效。
最左前缀原则决定能否走索引
MySQL、PostgreSQL、SQL Server等主流数据库都遵循“最左前缀匹配”规则:查询条件必须从联合索引的**最左侧列开始连续匹配**,中间不能跳过。例如索引是 (a, b, c):
- ✅
WHERE a = 1 AND b = 2—— 可用索引 - ✅
WHERE a = 1 ORDER BY b—— 可用索引做排序 - ❌
WHERE b = 2—— 索引失效,只能全表扫描 - ❌
WHERE a = 1 AND c = 3—— b 被跳过,c 无法利用索引
顺序影响数据局部性与查询效率
B+树中,数据是先按第一列全局排序,再在相同第一列值内按第二列排序,依此类推。这意味着:
- 第一列值越“筛选力强”(高选择性),越早缩小搜索范围,后续列处理的数据量就越小
- 但真正起决定作用的是**查询模式**,不是单纯选“区分度最高”的列放最前。比如高频等值查询
status = 'paid',即使选择性一般,也应靠左;而created_at > '2025-01-01'这类范围查询,更适合放在右侧 - 如果把范围查询列放在最左,会导致后续列基本无法参与索引查找(因为范围之后的数据不连续)
统计信息只基于首列,影响执行计划准确性
优化器依赖索引首列的统计直方图估算结果集大小。若把低选择性列(如 gender 只有男/女)放在第一位,统计信息会严重失真,导致优化器误判、放弃使用该索引,或选错连接方式。
例如索引定义为 (gender, user_id),优化器只看到 gender 的分布(约50%男/50%女),却不知道 user_id 在每个 gender 下是否高度分散——这会让它低估实际扫描行数,生成低效计划。
排序与分组也严格依赖顺序
当查询含 ORDER BY 或 GROUP BY 时,只有列顺序与索引定义完全一致(且无跳过),才能避免额外的文件排序(Using filesort):
- 索引 (city, age, name) 支持:
ORDER BY city, age✅,ORDER BY city✅ - 但不支持:
ORDER BY age❌,ORDER BY city, name❌(中间跳过了 age)
哪怕只是少一个等值条件,也可能让排序退化为内存或磁盘排序,显著拖慢响应。










