不可见索引是什么
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 之类的视图辅助判断索引是否长期闲置。