迁移后确认invisible索引未丢失的唯一可靠方法是查询information_schema.statistics表的is_visible字段,因mysqldump --no-create-info或降级到5.7会直接丢弃invisible属性,show index的visible列在8.0.12以下版本不可用,且主键、全文、空间索引严禁设为invisible。

迁移后怎么确认INVISIBLE索引没被误删或失效
跨版本迁移(比如从 8.0 升级到 5.7)或用 mysqldump --no-create-info 手动建表时,INVISIBLE 属性会直接丢失——不是“失效”,是根本没写进去。你看到的 SHOW INDEX FROM t\G 里 Visible: YES,很可能只是因为建表语句漏了关键字。
- 查
INFORMATION_SCHEMA.STATISTICS的IS_VISIBLE字段才是唯一可靠依据:SELECT INDEX_NAME, IS_VISIBLE FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = 'db' AND TABLE_NAME = 't'; - 如果迁移前用了
CREATE INDEX idx_x ON t(col) INVISIBLE;,迁移后必须手动补回:ALTER TABLE t ALTER INDEX idx_x INVISIBLE; -
mysqlpump和xtrabackup能保留可见性;但mysqldump输出的建表语句里若含INVISIBLE,低版本 MySQL 会报错ERROR 1064 (42000)
为什么ALTER TABLE ... INVISIBLE在迁移后突然不生效
不是语法错了,而是权限或版本限制被激活了:8.0.12+ 才在 SHOW INDEX 中暴露 Visible 列;低于该版本只能靠 INFORMATION_SCHEMA.STATISTICS.IS_VISIBLE 查。更隐蔽的是权限问题——操作 INVISIBLE 只需 INDEX 权限,但某些迁移脚本默认用 root 或最小权限账号,可能漏授。
- 执行
ALTER TABLE t ALTER INDEX idx_x INVISIBLE;报错ERROR 3522 (HY000): Primary key cannot be invisible?说明你试图隐藏主键——这在任何版本都不允许 - 报错
ERROR 1064 (42000)?大概率是客户端或中间件解析 SQL 时把INVISIBLE当成非法 token,检查是否连的是旧版 MySQL 或启用了兼容模式 - 命令成功但
IS_VISIBLE仍是 YES?确认是否在事务中执行且未提交,或被其他 DDL 并发阻塞(元数据锁 MDL 仍存在)
调优时怎么对比“有/无索引”的真实查询开销
别只看 EXPLAIN 的 key 字段——它对 INVISIBLE 索引恒为空。真正影响性能的是执行时的 I/O 和 CPU,得靠运行时指标交叉验证。
- 开启会话级开关再测:
SET SESSION optimizer_switch = 'use_invisible_indexes=on'; EXPLAIN SELECT * FROM t WHERE col = 1;,和关闭时的结果对比 - 盯紧
performance_schema.table_io_waits_summary_by_index_usage的COUNT_STAR和SUM_TIMER_WAIT,切为不可见后若某查询的Handler_read_next猛增,说明它原来真依赖这个索引 - 慢查询日志里同一语句的
Query_time和Rows_examined必须拉出来比——Rows_examined翻倍基本等于索引失效 - 注意:
FORCE INDEX (idx_x)对INVISIBLE无效,但USE INDEX (idx_x)在use_invisible_indexes=on下可用
哪些索引绝对不能设为INVISIBLE
主键、唯一约束依赖的索引、全文索引、空间索引——这些类型一旦尝试设为不可见,MySQL 会立刻拒绝,不给任何商量余地。最容易踩坑的是隐式主键:当表没有显式定义 PRIMARY KEY,InnoDB 会自建一个 GEN_CLUST_INDEX,它也属于主键范畴,无法隐藏。
-
UNIQUE KEY可以设为INVISIBLE,但要注意:如果该列被外键引用,或被触发器内查询显式依赖,切换后可能引发重复键错误或触发器变慢 - 函数索引(如
CREATE INDEX idx_upper ON t((UPPER(name))))支持INVISIBLE,但它的表达式计算开销仍在,写入性能不会改善 -
FULLTEXT和SPATIAL索引不支持INVISIBLE,DDL 会直接报错ERROR 1210 (HY000): Incorrect arguments to %s
真正容易被忽略的点:INVISIBLE 索引的磁盘占用和写入延迟一点没少,它只是让优化器“视而不见”。调优时盯着读性能,却忘了写负载可能已悄然升高——尤其在高频 INSERT/UPDATE 场景下,这点损耗会被放大。











