首页/数据/SQL 速查/不可见索引:上线前验证删索引
性能与执行计划72 条

不可见索引:上线前验证删索引

MySQL 8.0 支持把索引设为 INVISIBLE:优化器忽略它但索引仍被维护,用于验证“删掉这个索引会不会变慢”。

SQL 速查数据更新于 2026-10-13

不可见索引是什么

MySQL 8.0 引入不可见索引:把索引设为 INVISIBLE 后,优化器不再考虑它,但索引本身仍然存在、仍然随写入维护。这样就能在不真正删除的前提下验证「这个索引删掉会不会变慢」,出问题一条语句就能恢复可见,比删了再重建安全得多。

基本信息

适用平台MySQL 8.0+
语法ALTER TABLE 表 ALTER INDEX 索引名 INVISIBLE | VISIBLE
查看状态SHOW INDEX FROM 表 的 Visible 列
维护成本仍占磁盘空间并随写更新
限制主键不能设为不可见;外键相关索引有额外限制

典型使用场景

  • 删索引前的灰度验证,确认计划不退化再真正删除
  • 需要快速回退时:一条 ALTER 恢复可见即可
  • 测试环境验证优化器的选路偏好
  • 梳理表上一堆疑似冗余的索引,逐个隐藏观察
  • 与 EXPLAIN 对照,定位某个查询到底依赖哪个索引

隐藏与恢复

隐藏与恢复
ALTER TABLE orders ALTER INDEX idx_status INVISIBLE;   -- 优化器不再考虑该索引
SHOW INDEX FROM orders;                                -- Visible 列变为 No

EXPLAIN SELECT * FROM orders WHERE status = 'x';        -- 观察执行计划是否退化

-- 观察一个业务周期确认无影响后再真正删除
ALTER TABLE orders DROP INDEX idx_status;
-- 有问题就恢复可见
ALTER TABLE orders ALTER INDEX idx_status VISIBLE;

三种状态对照

状态优化器是否使用是否随写入维护是否占空间
VISIBLE(默认)是是是
INVISIBLE否是是
已 DROP不存在否已释放
隐藏唯一索引不会取消唯一性:索引仍在维护,重复值照样被拒绝,INVISIBLE 只影响优化器是否选用它。
不可见索引的价值在「可逆验证」:大表重建索引耗时长、期间写压力大,先隐藏再观察的风险远低于直接删除。可用 sys.schema_unused_indexes 之类的视图辅助判断索引是否长期闲置。

易错点

  • 把不可见当零成本下线:索引仍占磁盘并随每次写入维护,验证通过后要真正 DROP 才算省下资源
  • 隐藏后只观察几分钟就删:业务查询模式有周期性,月末报表与批量任务可能刚好没用上,至少覆盖一个完整业务周期
  • 对主键设置不可见:会被直接拒绝;外键依赖的索引也有额外限制,操作前先查依赖
  • 把 INVISIBLE 写进建表语句当长期配置:后来的人看不出索引为何不生效,隐藏应作为短期验证手段并记录原因
  • 只看一次 EXPLAIN 就下结论:计划会随数据分布与统计信息变化,验证期要覆盖典型查询并对比优化前的计划

数据来源与参考

  • MySQL 8.0 Reference Manual · Invisible Indexes
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌