不能直接看出重复索引,需结合Key_name、Column_name、Seq_in_index和Sub_part人工比对或通过INFORMATION_SCHEMA.STATISTICS聚合查询识别;UNIQUE和PRIMARY索引即使字段相同也不视为重复。
SHOW INDEX 能看出重复索引吗?
不能直接看出。show index from table_name 只列出索引定义,不标注“重复”,但你能肉眼比对:如果两个索引字段完全相同(顺序、类型、前缀长度都一致),且类型都是 btree,那就是重复索引。特别注意:key_name 不同但 column_name 和 seq_in_index 完全一致的,就是冗余索引。
怎么快速识别字段组合相同的重复索引?
用这条 SQL 查:
SELECT GROUP_CONCAT(DISTINCT Key_name) AS index_names, GROUP_CONCAT(DISTINCT Index_type) AS types, GROUP_CONCAT(DISTINCT Sub_part ORDER BY Sub_part) AS prefixes, Column_name, Seq_in_index FROM information_schema.STATISTICS WHERE Table_schema = 'your_db' AND Table_name = 'your_table' GROUP BY Column_name, Seq_in_index, Sub_part, Index_type HAVING COUNT(*) > 1;
它会把同一列位置、相同前缀、相同类型的索引聚在一起——只要 index_names 里出现多个名字,就说明建了重复索引。
- 别只看
Column_name,必须结合Seq_in_index和Sub_part(前缀长度)判断是否真重复 -
UNIQUE和PRIMARY索引即使字段相同也不算重复,它们承担约束职责 - Navicat 的「设计表 → 索引」界面无法自动标出重复,纯靠人眼横向对比字段顺序
Navicat 图形界面添加索引时容易埋下重复隐患
图形操作本身不校验已有索引,点几次「新增」就可能建出一模一样的索引。常见踩坑点:
- 建了
idx_user_status(user_id,status),又手抖建了个idx_usr_stat(user_id,status)——字段顺序、类型、前缀全同,就是重复 - 先建了普通索引,再用图形界面勾选「唯一」重新生成一个——不会覆盖,而是新增一个
UNIQUE索引,导致两套索引同时存在 - 大小写不敏感但 Navicat 生成的索引名用了不同大小写(如
IDX_USER和idx_user),在 MySQL 中视为不同索引,但实际功能完全重叠
删重复索引前必须确认它没被查询依赖
别看到重复就立刻 DROP INDEX。有些索引虽然字段一样,但一个是为 WHERE 加速,另一个是为 ORDER BY + LIMIT 覆盖扫描而建的,删掉可能让排序变慢。
- 先跑
EXPLAIN SELECT ...对比删前后执行计划,重点看key和Extra是否变化 - 检查慢查询日志或 Performance Schema,确认该索引最近是否被真实使用过
- 线上环境建议先
ALTER TABLE ... DISABLE KEYS(仅 MyISAM)或改名保留,观察一周再删
重复索引不是语法错误,但会拖慢写入、浪费内存、干扰优化器选择——发现后得逐个验证,不能靠名字或界面直觉下结论。


















