MySQL 隐藏索引
- 一、定义
- 二、核心操作
- 三、为什么需要隐藏索引?
- 四、避坑
一、定义
隐藏索引是一个 “待命” 的索引,平时不参与查询优化,但随时可以切换回来。
- “待命”因为物理存在:索引真实存在于磁盘上,并且会随着数据的增删改而实时更新。
- “不参与”因为逻辑不可见:对查询优化器来说,它就像不存在一样,优化器不会考虑使用它,即使你用
FORCE INDEX也不行。
二、核心操作
1、创建隐藏索引
-- 直接在 CREATE INDEX 语句末尾加上 INVISIBLE 即可。
CREATE INDEX idx_last_name ON customer(last_name) INVISIBLE;
2、修改现有索引的可见性
-- 隐藏索引
ALTER TABLE customer ALTER INDEX idx_last_name INVISIBLE;
-- 恢复可见
ALTER TABLE customer ALTER INDEX idx_last_name VISIBLE;
3 、强制优化器使用隐藏索引(测试使用)
默认情况下,优化器完全忽略隐藏索引。但可以通过系统变量在当前会话中临时改变这个行为:
-- 查看当前设置
SELECT @@optimizer_switch;
-- 在当前会话中,允许优化器使用隐藏索引
SET SESSION optimizer_switch="use_invisible_indexes=on";
三、为什么需要隐藏索引?
其作用在于安全地测试和管理索引。
场景一:安全删除索引
在生产环境中,删除一个索引风险很高,你不确定删除后会不会影响性能。
- 先把索引设为
INVISIBLE,观察一段时间。如果性能没有下降,再放心删除;如果出问题,立刻设回VISIBLE,无需重建。
场景二:测试新索引
当你想测试一个新索引的效果时:
- 创建一个
INVISIBLE的新索引。 - 在测试会话中,通过
optimizer_switch打开隐藏索引开关,验证性能提升。 - 验证通过后,再将其设为
VISIBLE正式使用。
场景三:优化器调试
当你怀疑某个索引导致优化器做出了错误选择时,可以将其隐藏,观察执行计划的变化,从而定位问题。
四、避坑
- 主键不能隐藏:主键索引是聚簇索引,是数据组织的核心,因此不能被设置为隐藏。
- 维护开销依然存在:即使索引是隐藏的,它依然会占用磁盘空间,并且在写入(INSERT/UPDATE/DELETE)时需要维护,所以不要滥用。
FORCE INDEX无效:即使你强制使用隐藏索引,优化器也会忽略它,除非你打开了use_invisible_indexes开关。