MySQL 8.0 虽然发布很久了,但可能大家都停留在 5.7.x,甚至更老,其实 MySQL 8.0 新增了许多重磅新特性,比如栈长今天要介绍的 "隐藏索引" 或者 "不可见索引"。

隐藏索引是什么鬼?

隐藏索引 字面意思就是把索引进行隐藏,即不可见,它不是用来查询优化的,所以它不会被优化器使用到。隐藏索引适用于除主键索引(显示或者隐式设置)之外的索引,意味着主键索引是不能通过任何方式隐藏的。

MySQL 数据库默认创建的索引都是可见的,要显式控制一个索引的可见性,可以在 CREATE TABLE,CREATE INDEX 或 ALTER TABLE 的索引定义命令中使用 VISIBLEINVISIBLE 关键字。

如下面示例所示:

CREATE TABLE javastack (
age INT,
weight INT,
tall INT,
INDEX age_idx (age) INVISIBLE
) ENGINE = InnoDB;
CREATE INDEX weight_idx ON javastack (weight) INVISIBLE;
ALTER TABLE javastack ADD INDEX tall_idx (tall) INVISIBLE;

要变更现有索引的可见性,可以在 ALTER TABLE ... ALTER INDEX 命令中使用 VISIBLEINVISIBLE 关键字。

年龄索引变更为不可见(隐藏):

ALTER TABLE javastack ALTER INDEX age_idx INVISIBLE;

年龄索引变更为可见:

ALTER TABLE javastack ALTER INDEX age_idx VISIBLE;

怎么知道一个表中的索引是可见还是不可见,可以从 INFORMATION_SCHEMA.STATISTICS 表,或者 SHOW INDEX 命令输出中获得。例如:

mysql> SELECT
INDEX_NAME,
IS_VISIBLE
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = 'db1' AND TABLE_NAME = 'javastack';
+------------+------------+
| INDEX_NAME | IS_VISIBLE |
+------------+------------+
| age_idx | YES |
| weight_idx | NO |
| tall_idx | NO |
+------------+------------+

隐藏索引有什么用?

从上面隐藏索引介绍我们知道,隐藏索引可以不被优化器所使用,那么我们可以把某个表的某个索引设置隐藏,然后再测试 SQL 语句的查询性能。

即可以利用隐藏索引快速测试删除索引后对 SQL 查询性能的影响,而无需进行索引删除、重建操作,如果需要该索引,再设置可见就好了,这在大表测试中无疑非常有用,因为对于大表索引的删除和重新添加很耗性能,甚至影响表的正常工作。

隐藏索引设置

如果一个索引被设置成隐藏了,但实际上又需要被优化器所使用,有几种表索引情况缺失对查询造成的影响:

1)SQL 查询语句中包含了索引提示指向不可见索引会发生错误;

2)性能模式数据中显示了受影响 SQL 查询语句的负载增高;

3)SQL 查询语句进行 EXPLIAN 时出现了不同的执行计划;

4)SQL 查询语句出现在了慢查询日志中(之前没有出现);

系统变量 optimizer_switch 的 use_invisible_indexes 标志的值,控制了优化器执行计划构建时是否使用隐藏索引。

如果 use_invisible_indexes 值设置为 off 关闭状态(默认值),优化器默认会忽略隐藏索引,即和加入该参数之前的效果一样。

如果 use_invisible_indexes 值设置为 on 打开状态,隐藏索引仍然保持不可见,但优化器会把隐藏索引加入到执行计划的构建中。

如果想要在某条单个 SQL 查询语句上启用隐藏索引,可以使用 SET_VAR 优化器提示来临时更新 optimizer_switch 的值,如下所示:

mysql> EXPLAIN SELECT /*+ SET_VAR(optimizer_switch = 'use_invisible_indexes=on') */
> age, weight FROM javastack WHERE weight >= 150\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: javastack
partitions: NULL
type: range
possible_keys: weight_idx
key: weight_idx
key_len: 5
ref: NULL
rows: 2
filtered: 100.00
Extra: Using index condition mysql> EXPLAIN SELECT age, weight FROM javastack WHERE weight >= 150\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: javastack
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 5
filtered: 33.33
Extra: Using where

索引的可见性不会影响索引的自身维护,例如,不管索引是可见还是不可见,每次表数据行的更改索引都会更新,并且唯一索引也可防止插入重复数据。

没有显式主键的表如果在 NOT NULL 列上有任何一个唯一索引,则仍可能成为有效的隐式主键。在这种情况下,第一个这样的索引会对表数据行施加与显式主键相同的约束,并且该索引不能设置为不可见。

如以下表的定义:

CREATE TABLE javastack (
age INT NOT NULL,
weight INT NOT NULL,
UNIQUE weight_idx (weight)
) ENGINE = InnoDB;

该表定义不包含任何显式主键,但是 weight 列为 NOT NULL,在该列上创建的唯一索引在数据行上与主键具有相同的约束,并且不能使其不可见:

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

假设现在我们将一个显式主键添加到表中:

ALTER TABLE javastack ADD PRIMARY KEY (age);

显式主键不能设置为不可见,此时,weight 列上的唯一索引不再充当隐式主键,因此可以使其设置不可见。

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

总结

本文介绍了 MySQL 8.0 中的新特性:隐藏(不可见)索引,这个索引并不是新加的索引类型,而是可以控制索引是否加入到执行计划的构建之中。

在实际生产中也可以利用隐藏索引进行 SQL 语句的性能测试,或者对索引进行逻辑删除,以及索引的灰度发布测试等,用处还是蛮大的。

本次的分享就到这里了,希望对大家有用。觉得不错,在看、转发分享一下哦~

最后,MySQL 系列教程还会继续更新,关注Java技术栈公众号第一时间推送,还可以在公众号菜单中获取历史 MySQL 教程,都是干货。

参考文档:

https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html

话说你们用的 MySQL 哪个版本呢?来投票一下!

另外,关注公众号Java技术栈,在后台回复:面试,可以获取我整理的 MySQL 系列面试题和答案,非常齐全。

版权申明:本文系公众号 "Java技术栈" 原创,原创实属不易,转载、引用本文内容请注明出处,禁止抄袭、洗稿,请自重,尊重他人劳动成果和知识产权。

近期热文推荐:

1.Java 15 正式发布, 14 个新特性,刷新你的认知!!

2.终于靠开源项目弄到 IntelliJ IDEA 激活码了,真香!

3.我用 Java 8 写了一段逻辑,同事直呼看不懂,你试试看。。

4.吊打 Tomcat ,Undertow 性能很炸!!

5.《Java开发手册(嵩山版)》最新发布,速速下载!

觉得不错,别忘了随手点赞+转发哦!

牛逼!MySQL 8.0 中的索引可以隐藏了…的更多相关文章

  1. MySQL 8.0 中统计信息直方图的尝试

    直方图是表上某个字段在按照一定百分比和规律采样后的数据分布的一种描述,最重要的作用之一就是根据查询条件,预估符合条件的数据量,为sql执行计划的生成提供重要的依据在MySQL 8.0之前的版本中,My ...

  2. MySQL 并行复制演进及 MySQL 8.0 中基于 WriteSet 的优化

    MySQL 8.0 可以说是MySQL发展历史上里程碑式的一个版本,包括了多个重大更新,目前 Generally Available 版本已经已经发布,正式版本即将发布,在此将介绍8.0版本中引入的一 ...

  3. MySql SqlServer Sqlite中关于索引的创建

    最近要更新Cocon90.Db库,令其ORM创建表时实现索引的添加.因此总结下列常用Sql,供大家学习与参考. 一.SqlServer中创建索引可以这样: ) Create Table Test ( ...

  4. (译)MySQL 8.0实验室---MySQL中的倒序索引(Descending Indexes)

    译者注:MySQL 8.0之前,不管是否指定索引建的排序方式,都会忽略创建索引时候指定的排序方式(语法上不会报错),最终都会创建为ASC方式的索引,在执行查询的时候,只存在forwarded(正向)方 ...

  5. 【Mysql】- Mysql 8.0正式版新亮点

    MySQL 8.0 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能! 注意:从 MySQL 5.7 升级到 MySQL 8 ...

  6. MySQL 8.0 正式版 8.0.11 发布:比 MySQL 5.7 快 2 倍

    ySQL 8.0 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能! 注意:从 MySQL 5.7 升级到 MySQL 8. ...

  7. MySQL 8.0 新特性梳理汇总

    一 历史版本发布回顾 从上图可以看出,基本遵循 5+3+3 模式 5---GA发布后,5年 就停止通用常规的更新了(功能不再更新了): 3---企业版的,+3年功能不再更新了: 3 ---完全停止更新 ...

  8. What's New In MySQL 8.0

        由于8.0内有很多C++11特性.需要gcc4.8版本以上.Rhel6系列默认gcc是4.7.在安装gcc6.1之后仍然检查不过. 原因可能是6.1版本不一定高于4.7,暂不讨论.鉴于升级gc ...

  9. MySQL 8.0的关系数据库新特性详解

    前言 MySQL 8.0 当前的最新版本是 8.0.4 rc,估计正式版本出来也快了.本文介绍几个 8.0 在关系数据库方面的主要新特性. 你可能已经知道 MySQL 从版本 5.7 开始提供了 No ...

随机推荐

  1. 《Spring Boot 实战纪实》之关键点文档

    目录 前言 (思维篇)人人都是产品经理 1.需求文档 1.1 需求管理 1.2 如何攥写需求文档 1.3 需求关键点文档 2 原型设计 2.1 缺失的逻辑 2.2 让想法跃然纸上 3 开发设计文档 3 ...

  2. Tomcat如何使用线程池处理远程并发请求

    Tomcat如何使用线程池处理远程并发请求 通过了解学习tomcat如何处理并发请求,了解到线程池,锁,队列,unsafe类,下面的主要代码来自 java-jre: sun.misc.Unsafe j ...

  3. Linux内核源码分析之setup_arch (三)

    1. 前言 在 Linux内核源码分析之setup_arch (二) 中介绍了当前启动阶段的内存分配函数memblock_alloc,该内存分配函数在本篇将要介绍paging_init中用于页表和内存 ...

  4. java图像开发学习——JTable之导入数据库

    package demo; import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.MouseAd ...

  5. ASP.Net中的TreeView控件中对节点的上移和下移操作

    Web中的TreeView中的没有PreNode和NextNode属性. 但它的集合属性中有一个IndexOf属性,从而能够找到它的前一个节点知后一个节点. TreeView中要么只有一个根节点:要么 ...

  6. ES6+Webpack+Babel基本环境搭建

    ### 本文基本是流水文,记录学习中步骤,希望对看到的你有用,蟹蟹. 基本环境搭建 技术栈 Webpack ES6 Babel 开发环境 VS Code Node 搭建环境过程 新建项目文件夹

  7. JS 学习 一

  8. 如何使用Pycharm在网页上展示诗歌。(HTML)

    !DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"&g ...

  9. 安卓mbn文件丢失,无法搜索移动信号,工程模式mbn乱改,不用QPST烧录怎样恢复?超简单!

    没有root,工程模式乱改mbn配置选项,导致mbn配置丢失,无法搜索移动网络. 重启若干次改配置都无效,清空网络设置无效,恢复出厂无效,recovery三清无效, 不太想拆机root麻烦,QPST配 ...

  10. 【项目实践】一文带你搞定Spring Security + JWT

    以项目驱动学习,以实践检验真知 前言 关于认证和授权,R之前已经写了两篇文章: [项目实践]在用安全框架前,我想先让你手撸一个登陆认证 [项目实践]一文带你搞定页面权限.按钮权限以及数据权限 在这两篇 ...