不可见索引是让优化器默认跳过但物理仍维护的索引;创建用create index ... invisible,切换用alter table ... alter index ... invisible,仅支持innodb b-tree索引,主键、fulltext和spatial索引不支持,验证需查information_schema.statistics.is_visible='no'并对比explain执行计划。

不可见索引不是“隐藏界面”,而是让优化器默认跳过它——写入开销、磁盘占用、唯一性校验全在,但执行计划里压根不出现。想靠它测试删索引的影响,必须确认它真被忽略,否则观察结果全是假阳性。
怎么创建或切换不可见索引
新建索引时直接加 INVISIBLE 最稳妥;已有索引只能用 ALTER TABLE ... ALTER INDEX ... INVISIBLE 切换,其他语法(如 SET INVISIBLE 或 MODIFY INDEX)会报错 ERROR 1064。
-
CREATE INDEX idx_user_status ON users(status) INVISIBLE;—— 推荐用于新索引,避免后续 DDL 锁风险 -
ALTER TABLE orders ALTER INDEX idx_created_at INVISIBLE;—— 唯一合法方式切换已有索引 - 主键、隐式主键(如首个
UNIQUE NOT NULL字段)、FULLTEXT和SPATIAL索引不支持设为不可见,尝试会触发ERROR 3522 - 操作只改元数据,毫秒级完成,不锁表、不重建 B+ 树,但长事务未提交时可能被 MDL 阻塞
怎么验证它真被优化器忽略了
别信 SHOW INDEX 的 Visible: NO 就算完事——得双重确认:查系统表 + 跑真实 EXPLAIN。
- 查
INFORMATION_SCHEMA.STATISTICS:SELECT IS_VISIBLE FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 'orders' AND INDEX_NAME = 'idx_created_at';,返回字符串'NO'才算生效 - 跑对比
EXPLAIN:EXPLAIN SELECT * FROM orders WHERE created_at > '2026-01-01';,若之前走该索引,现在key为空或换成别的索引,才说明生效 - 注意会话级干扰:执行
SELECT @@optimizer_switch LIKE '%use_invisible_indexes=on%';,如果返回 1,说明当前会话开了开关,EXPLAIN会“假装看见”它
为什么 EXPLAIN 不显示不可见索引,以及怎么让它临时现身
EXPLAIN 默认不把不可见索引纳入候选集,这是设计行为,不是 bug。想对比“有/无该索引”的真实影响,必须手动启用参与优化。
- 会话级启用(推荐):
SET SESSION optimizer_switch = 'use_invisible_indexes=on';,再跑EXPLAIN SELECT ... - SQL 级启用(更安全):
SELECT /*+ SET_VAR(optimizer_switch = "use_invisible_indexes=on") */ * FROM orders WHERE status = 'shipped';,然后EXPLAIN -
FORCE INDEX(idx_name)不是绕过可见性,而是直接报错ERROR 1176 (42000): Key 'idx_name' doesn't exist—— 优化器已将其逻辑注销,不能强制
压测时必须盯住的三个真实信号
单条 EXPLAIN 结果容易误判。真正影响性能的是线上负载,切换后至少观察 24 小时,覆盖完整业务周期。
- 查
performance_schema.table_io_waits_summary_by_index_usage的COUNT_STAR是否归零——但低频关键查询可能漏统计,不能当唯一依据 - 盯慢查询日志:特别是
Query_time突增、Rows_examined暴涨的语句 - 监控
Handler_read_next/Handler_read_rnd_next是否明显上升——这是全表扫描或回表激增的信号 - 应用层硬编码的
FORCE INDEX或 ORM 的USE INDEX提示会被忽略,导致查询失败,必须提前全局扫描清理
最易被忽略的是备份恢复行为:xtrabackup 物理备份保留可见性,而 mysqldump 默认不导出 INVISIBLE 属性,还原后索引自动变回 VISIBLE —— 这会导致“以为灰度成功,其实线上早失效”。











