判断重复唯一索引需确认同一表上两个UNIQUE索引覆盖的列组合完全一致(含顺序、前缀长度、NULL容忍等),如UNIQUE KEY idx_email(email)与UNIQUE KEY uk_user_email(email);通过information_schema.STATISTICS比对table_schema、table_name、column_name、sub_part、non_unique等字段;UNIQUE(a,b)与UNIQUE(b,a)不视为重复,email(100)和email(255)亦不可直接判重复。

直接删,但得先确认它真是“重复”的——不是名字不同、结构相同,就是冗余;否则删错索引会导致唯一性约束失效或查询变慢。
怎么判断一个唯一索引是不是重复的
重复唯一索引指:同一张表上,两个(或多个)UNIQUE索引覆盖的列组合完全一致(包括顺序、是否前缀索引、是否含NULL容忍等)。比如:UNIQUE KEY idx_email (email) 和 UNIQUE KEY uk_user_email (email) 就是典型重复。
- 查
information_schema.STATISTICS,重点比对:table_schema、table_name、index_name、seq_in_index、column_name、sub_part、non_unique(值为 0 表示唯一) - 注意:
UNIQUE KEY (a, b)和UNIQUE KEY (b, a)不算重复,顺序不同,最左前缀生效范围不同 - 含
sub_part的要小心:email(100)和email(255)在语义上可能不等价,不能直接判重复
删除重复唯一索引的正确写法
用 ALTER TABLE ... DROP INDEX,不是 DROP INDEX ... ON ...(后者在 MySQL 中不支持)。
- 语法统一为:
ALTER TABLE table_name DROP INDEX index_name; - 例如删掉冗余的
uk_email:ALTER TABLE users DROP INDEX uk_email; - 主键上的唯一约束不能用这个删——主键必须用
ALTER TABLE ... DROP PRIMARY KEY,且会同时删掉聚集索引,风险更高 - 删之前务必确认该索引没被应用逻辑依赖(比如 ORM 映射、唯一校验提示文案里写了索引名)
删完之后必须补唯一约束吗?
不一定,但大概率应该补——因为删的是“重复”,不是“多余”。你保留的那个索引得继续承担唯一性保障职责。
- 如果删完发现只剩一个索引,但名字不规范(比如叫
idx_uq_eml),建议重命名或重建:ALTER TABLE users DROP INDEX idx_uq_eml, ADD UNIQUE KEY uk_email (email); - 如果原有两个唯一索引,你删了一个,但业务仍要求多字段联合唯一(如
(email, tenant_id)),那保留的那个必须覆盖全部字段,否则约束失效 - 删完立刻执行
SHOW CREATE TABLE users;确认UNIQUE KEY还在,且定义符合预期
最容易被忽略的一点:唯一索引重复往往源于建表脚本多次执行、迁移工具自动补索引、或开发误加。删只是止血,得回溯为什么会出现——否则下次上线又来一遍。


















