如何利用MySQL 8.0的不可见索引进行无损生产环境调优?

轻丽小哥_8111

轻丽小哥_8111

2026-07-15

399人浏览

原创

不可见索引不是性能加速器,而是索引变更的“安全气囊”——它不能让查询变快,但能让你在删索引前确认不会变慢;alter table alter index invisible 是元数据级瞬时操作,仅翻转is_visible标志位,不重建索引、不锁表、不提升查询性能,专为安全验证索引价值而设计。

如何利用mysql 8.0的不可见索引进行无损生产环境调优?

不可见索引不是性能加速器,而是索引变更的“安全气囊”——它不能让查询变快,但能让你在删索引前确认不会变慢。

ALTER TABLE ALTER INDEX INVISIBLE 为什么必须写全语法

MySQL 8.0 只认 ALTER TABLE t1 ALTER INDEX idx_name INVISIBLE 这一种形式。写成 SET INVISIBLE、MODIFY INDEX idx_name INVISIBLE 或 ALTER INDEX idx_name INVISIBLE ON t1 全部报错 ERROR 1064 (42000)。这不是语法糖缺失,是设计上强制你显式声明表名和索引名,避免误操作扩散。

  • INVISIBLE 和 VISIBLE 是唯二合法关键字,大小写不敏感但建议全大写
  • 主键索引(含隐式主键)禁止设为不可见,执行直接触发 ERROR 3522 (HY000): Primary key cannot be invisible
  • 外键依赖的唯一索引、全文索引、空间索引同样不支持,提前查 INFORMATION_SCHEMA.STATISTICS 确认 INDEX_TYPE 和约束关系

EXPLAIN 看不到不可见索引?先关掉 use_invisible_indexes

默认情况下 EXPLAIN 压根不把 IS_VISIBLE = 'NO' 的索引纳入候选集,所以 key 字段为空或走别的索引,这正常。但很多人卡在:刚执行完 ALTER 就跑 EXPLAIN,发现还是走原索引——大概率是会话里开着 use_invisible_indexes=on。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • 查当前开关状态:SELECT @@optimizer_switch LIKE '%use_invisible_indexes=on%'
  • 临时关闭(推荐):SET SESSION optimizer_switch = 'use_invisible_indexes=off'
  • 别信 SHOW INDEX FROM t1\G 的 Comment 字段,它恒为 NULL;以 INFORMATION_SCHEMA.STATISTICS.IS_VISIBLE 为准,值是字符串 'YES' 或 'NO'

FORCE INDEX(idx_name) 报错 ERROR 1176 怎么办

这不是 bug,是设计行为:FORCE INDEX 要求索引逻辑存在且可见。一旦设为不可见,优化器在解析阶段就把它“注销”了,所以 ERROR 1176 (HY000): Key 'idx_name' doesn't exist 是必然结果,不是失效,是彻底不可见。

  • 应用层 ORM(如 MyBatis 的 @SelectKey、Django 的 extra())若硬编码了 FORCE INDEX 或 USE INDEX,切换后会直接失败,必须提前清理
  • 想对比“有/无该索引”的真实影响,只能用会话级开关:SET SESSION optimizer_switch = 'use_invisible_indexes=on',再跑 EXPLAIN
  • 单条 SQL 启用更安全:SELECT /*+ SET_VAR(optimizer_switch = "use_invisible_indexes=on") */ * FROM t1 WHERE ...

压测时盯住 Handler_read_rnd_next,不是只看 EXPLAIN

EXPLAIN 只反映单条语句的计划,而线上真实压力来自并发和数据分布。切换后至少观察 24 小时,覆盖完整业务周期,重点看三个信号:

  • Rows_examined 暴涨的语句(说明回表或扫描范围扩大)
  • Handler_read_rnd_next 明显上升(典型全表扫描或随机读激增)
  • performance_schema.table_io_waits_summary_by_index_usage.count_star 是否归零——但注意:低频关键查询(如凌晨报表)可能漏统计,不能当唯一依据

物理备份(如 xtrabackup)不保留 IS_VISIBLE 元数据,恢复后索引自动变回 VISIBLE;而 mysqldump 默认导出 INVISIBLE 属性,但 MySQL 5.7 及更低版本无法解析,回滚链路必须提前验证。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

2093

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

1279

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

755

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

2832

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

4708

4

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.08

1079

3

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

4971

4

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

2023.08.14

4422

7

mysql事务隔离级别
mysql事务隔离级别

mysql规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。本专题为大家提供mysql事务隔离级别相关的文章内容,大家可以免费体验。

2023.08.16

5794

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 180人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 287人学习