MySQL 5.7+ 支持 ALTER TABLE RENAME INDEX 语法,不锁表、不重建索引;5.6 及更早版本需先 DROP 再 ADD,存在无索引窗口且耗时长。

MySQL 5.7+ 直接用 RENAME INDEX 就行
只要你的 MySQL 版本 ≥ 5.7,改索引名就是一条语句的事,不用删再建,不锁表、不重建索引、不影响线上查询。
语法很简单:
ALTER TABLE `table_name` RENAME INDEX `old_index_name` TO `new_index_name`;
注意点:
-
old_index_name必须真实存在,且不能是PRIMARY -
new_index_name不能和表里已有的其他索引重名(包括UNIQUE、FULLTEXT等) - 索引列定义、类型、顺序完全不变,只是元数据层面改个名字
- 执行后
SHOW INDEX FROM table_name能立刻看到新名字
MySQL 5.6 及更早版本只能删+建
这些老版本压根不认 RENAME INDEX,强行执行会报错:ERROR 1064 (42000): You have an error in your SQL syntax。
必须分两步走,且这两步不能合并进一个 ALTER TABLE 语句(否则会报错):
ALTER TABLE `table_name` DROP INDEX `old_index_name`;<br>ALTER TABLE `table_name` ADD INDEX `new_index_name` (`col1`, `col2`);
关键风险:
- 中间存在短暂无索引窗口——DROP 后、ADD 前,如果此时有高频查询命中该字段,性能可能陡降
- ADD INDEX 会触发全量重建,大表耗时长、IO 高、可能阻塞写入
- 务必确认原索引类型(
UNIQUE、FULLTEXT)并在ADD时显式声明,否则默认建的是普通INDEX
别把 RENAME INDEX 和 RENAME TABLE 搞混
有人看到 RENAME 就下意识套用 RENAME TABLE 的写法,比如:
RENAME INDEX old_idx TO new_idx; -- ❌ 错!缺表名,语法非法
正确写法一定带表名,且结构固定:
- 必须以
ALTER TABLE开头 -
RENAME INDEX是子句,不是独立命令 - 不能省略反引号(尤其当索引名含特殊字符或关键字时)
错误示例还包括:
ALTER INDEX old_idx RENAME TO new_idx; -- ❌ 这是 Oracle/PostgreSQL 语法,MySQL 不支持
批量改索引名时,先查再跑,别硬编码
想给整个库的索引统一命名规范?别手写几十条 ALTER TABLE ... RENAME INDEX。先从 information_schema.statistics 查出要改的索引:
SELECT CONCAT('ALTER TABLE `', table_name, '` RENAME INDEX `', index_name, '` TO `', table_name, '_idx_', column_name, '`;')<br>FROM information_schema.statistics<br>WHERE table_schema = 'your_db'<br> AND index_name != 'PRIMARY'<br> AND seq_in_index = 1 -- 单列索引优先<br>ORDER BY table_name, index_name;生成完 SQL 后务必人工核对三件事:
- 目标索引是否真在当前表中(避免跨表误操作)
- 新名字是否与其他索引冲突(特别是联合索引拆分后重名)
- 是否漏掉了
UNIQUE或FULLTEXT索引——它们也得改,但命名逻辑可能不同
真正上线前,在测试库上跑一遍,再用 SHOW CREATE TABLE 确认结果。


















