mysql如何管理不可见索引_mysql Invisible Index测试应用

0次阅读

mysql 如何管理不可见索引_mysql Invisible Index 测试应用

怎么创建和切换不可见索引

MySQL 8.0+ 支持把索引设为 INVISIBLE,它仍被维护(插入 / 更新时会同步更新),但优化器默认不走它。创建时直接加 INVISIBLE 关键字就行:

CREATE INDEX idx_user_email ON users(email) INVISIBLE;

已有索引想临时“禁用”?用 ALTER TABLE …… ALTER INDEX …… INVISIBLE

ALTER TABLE users ALTER INDEX idx_user_email INVISIBLE;
ALTER TABLE users ALTER INDEX idx_user_email VISIBLE;

注意:只有 B-tree 索引支持不可见,FULLTEXTSPATIAL 不行;而且主键不能设为不可见——哪怕你试了也会报错:ERROR 3522 (HY000): A primary key index cannot be invisible

为什么不用 DROP 而用 INVISIBLE

删索引要重建表(除非是 MySQL 5.7+ 的 ALGORITHM=INSTANT,但仅限加字段、改列名等极少数操作),而设为不可见是秒级元数据变更,不锁表、不触发索引重建。

常见误判场景:线上怀疑某个索引拖慢写入,但不敢直接删——怕查询突然变慢。这时设为 INVISIBLE,观察几天 slow_query_logEXPLAIN 结果,确认没查询依赖它,再决定是否真正删除。

要点:

  • INVISIBLE 索引仍消耗磁盘空间、影响 INSERT/UPDATE/DELETE 性能
  • 它不会出现在 SHOW INDEX 的默认结果里,得显式查:SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE INDEX_NAME = 'xxx' AND TABLE_NAME = 'users'
  • FORCE INDEX 无法强制走不可见索引,会报错:ERROR 1176 (42000): Key 'idx_user_email' doesn't exist in table'users'

测试时容易忽略的 optimizer_switch 设置

MySQL 默认开启 use_invisible_indexes,所以 INVISIBLE 索引真“不可见”。但如果你在测试中想临时让优化器考虑它(比如验证“如果启用这个索引,执行计划会不会变好”),得手动打开开关:

SET SESSION optimizer_switch = 'use_invisible_indexes=on';

注意:

  • 这个开关只对当前 session 生效,不影响其他连接
  • 全局设置需 SET GLOBAL,但生产环境慎用,可能意外改变所有查询行为
  • 开关关闭时,哪怕你写 USE INDEX(idx_user_email),也会被无视,不是报错而是静默降级到全表扫描或其它可用索引

EXPLAIN 看不见 INVISIBLE 索引,但 performance_schema 能挖出来

EXPLAIN 输出里永远看不到不可见索引——它压根不在候选索引列表里。但如果你怀疑某条慢查本该走它,又不确定是不是被设 invisble 了,可以查 performance_schema.table_io_waits_summary_by_index_usage

SELECT OBJECT_NAME, INDEX_NAME, COUNT_READ FROM performance_schema.table_io_waits_summary_by_index_usage WHERE OBJECT_NAME = 'users' AND INDEX_NAME IS NOT NULL ORDER BY COUNT_READ DESC;

这个视图会统计每个索引的实际使用次数,包括 INVISIBLE 的——只要某次查询显式指定过(比如 FORCE INDEX),或者 session 开了 use_invisible_indexes=on,它就会被计数。

关键点:

  • 该视图默认关闭收集,需提前开:UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME = 'events_waits_history_long';
  • COUNT_READ 是累计值,重启后清零,别拿单次结果下结论
  • 如果一个 INVISIBLE 索引的 COUNT_READ 长期为 0,基本可确认没业务路径在用它

不可见索引不是“隐身术”,而是“选择性失明”——对优化器不可见,但对存储引擎、复制、备份、监控全透明。最容易翻车的地方,就是以为设成 INVISIBLE 就彻底没开销了,其实写放大和空间占用一点没少。

星耀云
版权声明:本站原创文章,由 星耀云 2026-03-15发表,共计1876字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources