隐藏索引是元数据级“软禁”,非物理删除;仅修改IS_VISIBLE标志,毫秒完成、无锁不阻塞,专解“删前不敢试”痛点,但写入开销与空间占用均不变。

隐藏索引不是“删不了”,而是“先不让你用”——它真正解决的是「删之前不敢试」这个卡点。
ALTER INDEX ... INVISIBLE 是元数据操作,不是删除
执行 ALTER TABLE t1 ALTER INDEX idx_name INVISIBLE 仅修改数据字典里的 IS_VISIBLE 标志,不重建 B+ 树、不锁表、不阻塞写入。大表也能毫秒完成。
- 对比
DROP INDEX:后者要重写整个索引结构,可能耗时数小时,且不可逆(除非有备份) - 对比
CREATE INDEX:新建索引会加 S 锁、阻塞 DML,而设为不可见完全无锁 - 注意:主键索引(含隐式主键)和唯一约束依赖的第一个唯一索引,强制设为
INVISIBLE会报错ERROR 3522 (HY000)
压测时必须打开 use_invisible_indexes=ON 才能验证效果
默认情况下优化器彻底忽略不可见索引,EXPLAIN 看不到它——但这不代表你真能复现“删掉它之后的性能”。要闭环验证,必须临时启用:
- 在压测连接里执行
SET SESSION optimizer_switch='use_invisible_indexes=ON' - 再跑
EXPLAIN FORMAT=JSON,检查used_indexes和key字段是否出现该索引名 - 全局设置
SET GLOBAL会影响所有新会话,生产环境严禁使用 - 如果应用里写了
FORCE INDEX(idx_name),哪怕索引不可见也会直接报错ERROR 1176,必须提前扫描代码/ORM 配置
备份恢复后可见性状态可能丢失
mysqldump 默认保留 INVISIBLE 属性,但物理备份工具(如 xtrabackup)不保存该元数据。恢复后索引可能意外变回 VISIBLE,导致压测结论失效。
- 验证方式:恢复后立刻查
INFORMATION_SCHEMA.STATISTICS的IS_VISIBLE列 - 分区表上对某一分区设为不可见,其他分区不受影响;但执行
ALTER TABLE ... REORGANIZE PARTITION可能重置可见性 - 不可见索引仍参与写入维护:
INSERT/UPDATE/DELETE一样更新 B+ 树页,不会降低写延迟
最易被忽略的一点:不可见索引不省空间、不减写开销,只改优化器决策。想靠它“缓解负载”是典型误判——它只回答“要不要用”,不回答“要不要存”。


















