学到了!MySQL 8 新增的「隐藏索引」真不错

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_VISIBLEFROM INFORMATION_SCHEMA.STATISTICSWHERE 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: 1select_type: SIMPLEtable: javastackpartitions: NULLtype: range
possible_keys: weight_idxkey: weight_idxkey_len: 5ref: NULLrows: 2filtered: 100.00Extra: Using index conditionmysql> EXPLAIN SELECT age, weight FROM javastack WHERE weight >= 150\G
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: javastackpartitions: NULLtype: ALL
possible_keys: NULLkey: NULLkey_len: NULLref: NULLrows: 5filtered: 33.33Extra: 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 语句的性能测试,或者对索引进行逻辑删除,以及索引的灰度发布测试等,用处还是蛮大的。

参考文档:

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

话说你们用的 MySQL 哪个版本呢?


往期推荐

忘记MySQL密码怎么办?一招教你搞定!

2020-10-20

MySQL为Null会导致5个问题,个个致命!

2020-12-31

很实用的21个SQL小技巧!

2020-11-03

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544968.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java ClassLoader findLibrary()方法与示例

ClassLoader类findLibrary()方法 (ClassLoader Class findLibrary() method) findLibrary() method is available in java.lang package. findLibrary()方法在java.lang包中可用。 findLibrary() method is used to find the absolute pathname of the given native library. f…

iOS开发-自定义UIAlterView(iOS 7)

App中不可能少了弹框,弹框是交互的必要形式,使用起来也非常简单,不过最近需要自定义一个弹框,虽然iOS本身的弹框已经能满足大部分的需求,但是不可避免还是需要做一些自定义的工作。iOS7之前是可以自定义AlterView的&am…

jsp中redirect和forward的区别

在网上看到一些帖子,总结了一些区别,可以从以下几个方面来看:1.从地址栏显示来说 forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来…

Spring 事务失效的 8 大场景,面试官直呼666...

前几天发了一篇文章里面有一个关于事务失效的问题:用 Spring 的 Transactional 注解控制事务有哪些不生效的场景?其中有个热心粉丝留言分享了下,我觉得总结得有点经验,给置顶了:但是我觉得还是总结得不够全&#xff0c…

python 示例_Python条件类| release()方法与示例

python 示例Python Condition.release()方法 (Python Condition.release() Method) release() is an inbuilt method of the Condition class of the threading module in Python. release()是Python中线程模块的Condition类的内置方法。 Condition class implements conditio…

Java BigInteger类| hashCode()方法与示例

BigInteger类hashCode()方法 (BigInteger Class hashCode() method) hashCode() method is available in java.math package. hashCode()方法在java.math包中可用。 hashCode() method is used to return the hash code value of this BigInteger. hashCode()方法用于返回此Big…

认真聊一下MySQL索引的底层实现!

前言当我们发现SQL执行很慢的时候,自然而然想到的就是加索引,当然他也是高频的面试问题,所以今天我们一起来学习一下MySQL索引的底层实现:B树。树简介、树种类B-树、B树简介B树插入B树查找B树删除B树经典面试题树的简介树的简介树…

js的四舍五入

Math.ceil求最小的整数但不小于本身. Math.round求本身的四舍五入。 Math.floor求最大的整数但不大于本身.

Java BigInteger类| bitCount()方法与示例

BigInteger类的bitCount()方法 (BigInteger Class bitCount() method) bitCount() method is available in java.math package. bitCount()方法在java.math包中可用。 bitCount() method is used to count the number of bits in 2’s complement denotation of this BigIntege…

head first python(第三章)–学习笔记

1.介绍基础文件,输入,输出 open() 打开文件,一次传入一行数据,可以结合for循环和readline()来使用 close() 用来关闭open打开的文件 the_file open(sketch.txt)the_file.close()例子: >>> data open(/root/…

最新大厂面试真题集锦

年后又是一波求职季,正是“金三银四”这个求职黄金期,很多人扎堆在这个时间段跳槽,找工作,程序员也不例外。春节刚过,各公司企业都开始启动了新一年的招聘计划,招聘岗位倍增,求职人数远超于岗位…

java.lang.IllegalThreadStateException 线程运行报错

写程序线程再运行第二遍的时候报java.lang.IllegalThreadStateException。发现一个Thread不能重复用start方法。 解决方法: 1、将extends Thread线程类改成implements Runnable,或者将Thread a new Thread改为Runnable a new Runnable; …

使用OpenCV在Python中进行人脸和眼睛检测

Modules Used: 使用的模块: python-opencv(cv2)python-opencv(cv2) python-opencv(cv2) Opencv(Open source computer vision) is a python library that will help us to solve computer vision problems. Opencv(开源计算机视觉)是一个Python库,可帮…

Java打造一款SSH客户端,已开源!

最近由于项目需求,项目中需要实现一个WebSSH连接终端的功能,由于自己第一次做这类型功能,所以首先上了GitHub找了找有没有现成的轮子可以拿来直接用,当时看到了很多这方面的项目,例如:GateOne、webssh、she…

html中可以自定义属性,,,妈的竟然才知道..

html中可以自定义属性,,,妈的竟然才知道.. <input userinfo"没见过帅哥呀" />

Js实现动态插入删除文本框

自己做了个Js插入文本框的例子&#xff0c;扔上别忘了。 <html><head><title>Untitled Document</title><meta http-equiv"Content-Type" content"text/html; charsetutf-8"><script language"javascript"&g…

ruby 数组元素替换_从Ruby中的集合中删除并替换元素

ruby 数组元素替换Ruby has various specific methods to fulfil specific tasks. At several places, you may need to replace or delete an element from an instance of set class provided that there are certain elements present in the Set. You can perform deletion…

我去,这几个Linux指令太装B了|动图展示

1. sl先看一下呼啸而过的火车&#xff1b;安装指令如下&#xff1b;sduo apt-get install sl执行结果如下&#xff1a;2. htop图形化Linux系统性能监测工具&#xff0c;屌不屌:安装指令如下:sduo apt-get install htop执行结果如下&#xff1b;3. gcp以前用cp复制文件总是看不懂…

书店POS机--细化迭代2--测试

2019独角兽企业重金招聘Python工程师标准>>> (1) 开始一次新的销售&#xff0c;点击书店POS系统的销售&#xff1a; (2) 进入销售模块之后的界面如下&#xff1a; (3)逐条录入商品条目(根据商品编号)&#xff0c;并修改数量。确认无误之后点击“确认”按钮&#x…

XML文件的写入和读取(解析)基于DOM4J工具

这两天做了个天气的小应用&#xff0c;需要用到百度的天气api&#xff0c;获取到的信息是一个xml文档。 所以就从网上查了一下相关的知识&#xff0c;就是关于怎么去解析出来xml文件的信息。 先放一个我自己写的例子&#xff0c;加了点注释&#xff0c;贴这里吧。 package cn…