MySQL 8.0 新特性之隐藏索引

文章目录

原文地址:MySQL 8.0 Reference Manual

我在慕课网发布的免费视频讲解 MySQL 8.0 版本新特性。

MySQL 8.0 支持隐藏索引(invisible index),也称为不可见索引。隐藏索引不会被优化器使用。主键不能设置为隐藏(包括显式设置或隐式设置)。

索引默认是可见的(visible)。使用CREATE TABLECREATE INDEXALTER TABLE语句的VISIBLE或者INVISIBLE选项设置一个新建索引的可见性:

CREATE TABLE t1 (
  i INT,
  j INT,
  k INT,
  INDEX i_idx (i) INVISIBLE
) ENGINE = InnoDB;
CREATE INDEX j_idx ON t1 (j) INVISIBLE;
ALTER TABLE t1 ADD INDEX k_idx (k) INVISIBLE;

使用ALTER TABLE ... ALTER INDEX语句的VISIBLE或者INVISIBLE选项修改已有索引的可见性:

ALTER TABLE t1 ALTER INDEX i_idx INVISIBLE;
ALTER TABLE t1 ALTER INDEX i_idx VISIBLE;

通过数据字典表 INFORMATION_SCHEMA.STATISTICS 或者SHOW INDEX命令可以查看索引的可见性。例如:

mysql> SELECT INDEX_NAME, IS_VISIBLE
       FROM INFORMATION_SCHEMA.STATISTICS
       WHERE TABLE_SCHEMA = 'db1' AND TABLE_NAME = 't1';
+------------+------------+
| INDEX_NAME | IS_VISIBLE |
+------------+------------+
| i_idx      | YES        |
| j_idx      | NO         |
| k_idx      | NO         |
+------------+------------+

不可见索引特性可以用于测试删除某个索引对于查询性能的影响,同时又不需要真正删除索引,也就避免了错误删除之后的索引重建。对于一个大表上的索引进行删除重建将会非常耗时,而将其设置为不可见或可见将会非常简单快捷。

如果某个设置为隐藏的索引实际上仍然需要或者被优化器所使用,可以通过以下多种方法发现缺少该索引带来的影响:

  • 索引提示中使用了该索引的查询将会产生错误。
  • 性能模式(Performance Schema)中的数据显示受影响查询的负载升高。
  • EXPLAIN 语句显示了不同的查询执行计划。
  • 慢查询日志中出现了新的查询语句。

系统变量 optimizer_switch 的 use_invisible_indexes 值控制了优化器构建执行计划时是否使用隐藏索引。如果设置为 off (默认值),优化器将会忽略隐藏索引(与引入该属性之前的行为相同)。如果设置为 on,隐藏索引仍然不可见,但是优化器在构建执行计划时将会考虑这些索引。

索引的可见性不会影响索引的维护。例如,无论索引是否可见,每次修改表中的数据时都需要对相应索引进行更新,而且唯一索引都会阻止插入重复的列值。

一个没有明确定义主键的表仍然可能存在有效的隐式主键( 表中某些 NOT NULL 字段上创建了 UNIQUE 索引)。在这种情况下,表中第一个这样的索引和显式主键存在相同的约束效果,该索引也不能被设置为不可见。假如存在以下表定义:

CREATE TABLE t2 (
  i INT NOT NULL,
  j INT NOT NULL,
  UNIQUE j_idx (j)
) ENGINE = InnoDB;

定义中没有明确指定主键,但是 NOT NULL 字段 j 上存在一个唯一索引,它实现了和主键相同的数据约束,不能设置为不可见:

mysql> ALTER TABLE t2 ALTER INDEX j_idx INVISIBLE;
ERROR 3522 (HY000): A primary key index cannot be invisible.

如果为该表指定一个显式的主键:

ALTER TABLE t2 ADD PRIMARY KEY (i);

该主键不能设置为不可见。除此之外,字段 j 上的唯一索引不再是一个隐式的主键,因此可以设置为隐藏索引:

mysql> ALTER TABLE t2 ALTER INDEX j_idx INVISIBLE;
Query OK, 0 rows affected (0.03 sec)

隐藏索引应用场景:软删除、灰度发布。

欢迎留言讨论!

你可能感兴趣的:(MySQL)