MySQL索引顺序的优化直接影响查询性能,尤其在复合索引(多列索引)中尤为关键。合理的索引列顺序可以显著提升查询效率、减少扫描行数,并避免额外的排序或临时表操作。
理解最左前缀原则
复合索引遵循“最左前缀”匹配规则,即查询条件必须从索引的最左列开始,且中间不能跳过列。例如,索引 (a, b, c),以下查询能命中:
WHERE a = 1 WHERE a = 1 AND b = 2 WHERE a = 1 AND b = 2 AND c = 3但 WHERE b = 2 或 WHERE a = 1 AND c = 3 只能部分使用或无法使用该索引。因此,索引列顺序应优先将筛选性高、常用于等值查询的列放在前面。
将高选择性的列前置
选择性是指某列不同值的数量与总行数的比例。选择性越高,过滤效果越好。例如用户表中的 email 列通常比 gender 列选择性高。在创建复合索引时,应尽量将选择性高的列放在前面,以快速缩小结果集。
可以通过以下SQL评估列的选择性:
SELECT COUNT(DISTINCT column_name) / COUNT(*) FROM table_name;结果越接近1,选择性越高。若某列选择性极低(如状态字段只有0/1),可考虑不将其作为复合索引的首列。
兼顾查询模式与排序需求
索引顺序还需匹配实际查询场景。如果常见查询包含 ORDER BY 或 GROUP BY,应让索引顺序覆盖这些子句,避免 filesort 或临时表。
例如查询为:
SELECT * FROM orders WHERE user_id = 123 ORDER BY created_time DESC;此时创建索引 (user_id, created_time) 可同时满足条件过滤和排序,无需额外排序操作。
注意:范围查询列(如 >, 10,索引应为 (a, b),而不是 (b, a)。
避免冗余与重复索引
过多或重复的索引会增加写操作开销并占用存储空间。例如已有索引 (a, b),再创建 (a) 就是冗余的,因为最左前缀已覆盖单列 a 的查询。但 (b, a) 与 (a, b) 不是等价的,不能互相替代。
建议定期审查索引使用情况:
SHOW INDEX FROM table_name;SELECT * FROM performance_schema.table_io_waits_summary_by_index_usage WHERE table_name = 'your_table';找出未被使用的索引并进行清理。
基本上就这些。索引顺序不是一成不变的,需结合具体查询语句、数据分布和业务变化持续调整。通过分析执行计划(EXPLAIN)验证索引是否生效,是优化过程中必不可少的一步。
