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

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

  1. 职业高中学计算机高考后能报什么,「新高考」新高考选哪些科目可以报计算机专业?高中生如何提分?...

    摘要: 「新高考」新高考选哪些科目可以报计算机专业?高中生如何提分?为你介绍为了让大家详细的了解关于新高考,计算机专业,高中生的一些信息内容,招生网为大家整理了<「新高考」新高考选哪些科目可以报 ...

  2. Yoshua Bengio团队通过在网络「隐藏空间」中使用降噪器以提高深度神经网络的「鲁棒性」...

    原文来源:arXiv 作者:Alex Lamb.Jonathan Binas.Anirudh Goyal.Dmitriy Serdyuk.Sandeep Subramanian.Ioannis Mit ...

  3. Yoshua Bengio团队通过在网络「隐藏空间」中使用降噪器以提高深度神经网络的「鲁棒性」

    原文来源:arXiv 作者:Alex Lamb.Jonathan Binas.Anirudh Goyal.Dmitriy Serdyuk.Sandeep Subramanian.Ioannis Mit ...

  4. 关于 MySQL 8.0 新特性“隐藏索引”的一点思考

    MySQL 8.0有一个称为"隐藏索引"的新功能,它允许快速启用/禁用MySQL Optimizer使用的索引. 在此分享一些对这个新功能的首次使用经验和想法. 对我们有什么用? ...

  5. 今天,我们来深挖一位链游和NFT界的「隐藏大佬」

    在这波以「DeFi 玩法+万物 NFT」主导的新浪潮中,MixMarvel 有何动作? 作者 | 秦晓峰  编辑 | 郝方舟 出品 | Odaily星球日报(ID:o-daily) 提起初代区块链游戏 ...

  6. mysql数据字典生成器_「python技术」列表推导、生成器表达式和字典推导的差异及其示例

    #开往春天新创作大赛# 前言 列表推导式构建列表的快捷方式,而生成器表达式则可以用来创建其他任何类型的序列.自python2.7以后,列表推导和生成器表达式的概念就应用到了字典上,所以就有了字典推导, ...

  7. mysql虚拟列表_「前端进阶」高性能渲染十万条数据(虚拟列表)

    前言 在工作中,有时会遇到需要一些不能使用分页方式来加载列表数据的业务情况,对于此,我们称这种列表叫做长列表.比如,在一些外汇交易系统中,前端会实时的展示用户的持仓情况(收益.亏损.手数等),此时对于 ...

  8. mysql insert 嵌套_「insert语句」数据库插入insert语句中添加嵌套查询select - seo实验室...

    insert语句 示例: insert into mytable(X,Y,Z) Values((SELECT X from basetable WHERE ID = 8),(SELECT Y from ...

  9. 游戏的「隐藏身份」:AI与现实世界的「王牌训练师」

    来源:雷锋网 虚拟游戏对人工智能的物理性优势已经开始显现. 「注:文章来自国际电信联盟(ITU)」 当谈到新兴技术在改善世界各地人们生活的潜力时,你首先想到的可能不是电子游戏.然而,虚拟游戏可以在训练 ...

最新文章

  1. 请大家访问另一个我的博客!
  2. 游戏安全有多重要?——GAME-TECH游戏开发者技术沙龙
  3. 撩课-Web大前端每天5道面试题-Day24
  4. linux 网络RPS/RFS/XPS
  5. ie浏览器网页版进入_IE浏览器打开网页提示无法打开Internet站点的解决办法
  6. 数据库的开发笔记-字典表
  7. 理论基础 —— 索引 —— 倒排索引
  8. caffe prototxt 可视化工具
  9. c#中queue的用法
  10. 64位系统目录在那里_教你玩转Linux系统目录结构
  11. 夯实Java基础(二十)——JAVA正则表达式
  12. [ASP.NET MVC]通过对HtmlHelper扩展简化“列表控件”的绑定
  13. 国家一级计算机考试选择题题库,计算机一级考试选择题题库与答案2016
  14. extern作用详解
  15. QMUI框架简介,android开发游戏
  16. vue前端跨域解决方案
  17. 被互联网婚恋榨干的你,还会相信爱情吗?
  18. u检验和t检验区别与联系
  19. 下面哪个不是python常用的开发工具_Python程序员常用的IDE和其它开发工具
  20. 实现Ubuntu与Windows之间的复制粘贴

热门文章

  1. 苹果7手机严重卡顿_苹果手机仅配备4GB运存都不会卡顿,安卓系统为何要更多内存?...
  2. Ubuntu18.0.1 安装 anaconda conda cudnn pytorch-gpu
  3. Ubuntu18使用docker快速安装oracle 11g
  4. 利用人工智能提升团队包容性
  5. HDU 3530Subsequence(单调队列)
  6. 基于百度语音识别API的Python语音识别小程序
  7. springJdbc in 查询,Spring namedParameterJdbcTemplate in查询
  8. greenlet 详解
  9. Struts2 ActionWildcard(通配符配置)约定优于配置
  10. VMware 11安装Mac OS X 10.10 及安装Mac Vmware Tools.