MySQL允许一张表创建多个索引,但需权衡写性能、空间与优化器选错风险;复合索引须遵守最左前缀原则,高频查询类型决定索引策略,冗余索引应定期清理。
MySQL 支持在一张表上创建多个索引
可以,而且很常见。MySQL(包括 InnoDB 和 MyISAM)允许对同一张表创建多个单列索引、复合索引,甚至函数索引(8.0.13+),只要不违反唯一性约束或索引长度限制。
但“能建”不等于“该建”。多个索引会带来写性能下降(INSERT/UPDATE/DELETE 需同步更新所有相关索引)、磁盘空间占用增加,以及优化器可能选错索引的风险。
-
SHOW INDEX FROM table_name可查看当前所有索引 - 单列索引过多容易导致
Using filesort或Using temporary,尤其在ORDER BY + LIMIT场景下 - InnoDB 中,主键索引(聚簇索引)本身会影响二级索引结构——所有二级索引叶子节点都存主键值,所以主键不宜过长(如用 UUID 作主键会放大二级索引体积)
复合索引的最左前缀原则必须严格遵守
这是 MySQL 索引失效最常见的原因。只有查询条件中包含复合索引的**连续左侧字段**,才能命中该索引。
例如有索引 INDEX idx_user_status_created (user_id, status, created_at):
- ✅
WHERE user_id = 123 AND status = 'active'—— 命中前两列 - ✅
WHERE user_id = 123—— 命中第一列 - ❌
WHERE status = 'active'—— 跳过user_id,无法使用该索引 - ❌
WHERE user_id = 123 AND created_at > '2024-01-01'——status未出现在条件中,created_at无法利用(范围查询后列失效)
注意:等值查询(=、IN)可跳过中间列?不行。只有 IN 在某些版本中可能触发“index merge”,但不可依赖,且效率通常不如设计合理的复合索引。