不可见索引是 MySQL 8.0 新增的特性。提供将索引标记为 “不可被优化器使用” 的能力。这意味着索引仍会被维护并随着数据更新而更新,但没有查询被允许使用索引(即时查询中用了FORCE INDEX index_name
强制使用索引)。
不可见索引不应与 “禁用索引” 混淆。禁用索引是 MyISAM 储存引擎实现的,禁用的索引会停止维护。不可见索引有两个重要使用场景:
- 逻辑删除。当生产环境中要执行删除操作时,通常会希望再次观察数据。而不可见索引可以考虑为索引的“回收站”。如果弄错了索引,并希望再次使用,只需要修改其为可见的——比重建索引或从备份中恢复快很多。例子如下:
ALTER TABLE Country ALTER INDEX c INVISIBLE;
- 灰度发布。添加索引时,考虑它可能改变你现有的查询计划是很重要的——有时会变成你不希望的方式。不可见索引提供了在需要时灰度发布索引的机会,让你得以持续观察系统状态,并避免了(如果删除索引)负荷过高的可能。例子如下:
ALTER TABLE Country ADD INDEX c (Continent) INVISIBLE; -- 经过一段时间后 ALTER TABLE Country ALTER INDEX c VISIBLE;
所有索引在未指定时,都是默认可见的。你可以在information_schema.statistics
中搜索到所有不可见索引。
SELECT * FROM information_schema.statistics WHERE is_visible='NO';
*************************** 1. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: world
TABLE_NAME: Country
NON_UNIQUE: 1
INDEX_SCHEMA: world
INDEX_NAME: c
SEQ_IN_INDEX: 1
COLUMN_NAME: Continent
COLLATION: A
CARDINALITY: 7
SUB_PART: NULL
PACKED: NULL
NULLABLE:
INDEX_TYPE: BTREE
COMMENT: disabled
INDEX_COMMENT:
IS_VISIBLE: NO
提示
移除不需用到的索引。当发现索引影响了修改操作的性能时,这就是一个可行的简化。索引同样会影响读取时的性能,因为优化器需要为它们评估查询计划。
译自:
Invisible Indexes – The Unofficial MySQL 8.0 Optimizer Guide