首页 > 数据库 >MySQL8.0新特性之:不可见索引

MySQL8.0新特性之:不可见索引

时间:2023-10-30 14:39:02浏览次数:45  
标签:c3 index idx 特性 索引 MySQL8.0 test c2 NULL

概念描述

  MySQL从8.0版本开始支持不可见索引(invisible index)也可叫隐式索引,隐形索引或者隐藏索引。不可见索引是不被MySQL优化器使用的,但是优化器会正常维护它。

使用场景

  1. 非主键上的索引使用
  2. 测试删除索引对性能的影响,而无需进行破坏性更改(通常对于大表来说,删除或者重建索引的影响很大,可以通过设置invisible/visible 属性来验证索引带来的效果)

测试验证

1. 创建不可见索引
#### 建表时指定索引的 invisible属性:
mysql >create table test(
    -> id int not null primary key,
    -> c1 int default 0,
    -> c2 int not null default 0,
    -> index idx_c2(c2) invisible);
Query OK, 0 rows affected (0.00 sec)

#### 查看建表语句会显示索引的INVISIBLE提示信息:/*!80000 INVISIBLE */
mysql >show create table test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int NOT NULL,
  `c1` int DEFAULT '0',
  `c2` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `idx_c2` (`c2`) /*!80000 INVISIBLE */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
1 row in set (0.00 sec)


#### 通过create index命令创建
mysql >create index idx_test_c1 on test(c1) invisible;
Query OK, 0 rows affected (3.65 sec)
Records: 0  Duplicates: 0  Warnings: 0

#### 通过alter table XXX add index 命令创建
mysql >alter table test add index idx_test_c3(c3) invisible;
Query OK, 0 rows affected (0.21 sec)
Records: 0  Duplicates: 0  Warnings: 0

2. 更改不可见索引

   要调整现有索引的可见性,请使用 VISIBLE 或者 INVISIBLE 关键字并通过语法: alter table… alter index 进行操作:

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

mysql >alter table test alter index idx_test_c1 visible;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql >alter table test alter index idx_c2 visible;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql >show create table test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int NOT NULL,
  `c1` int DEFAULT '0',
  `c2` int NOT NULL DEFAULT '0',
  `c3` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `idx_c2` (`c2`),
  KEY `idx_test_c1` (`c1`),
  KEY `idx_test_c3` (`c3`) /*!80000 INVISIBLE */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
1 row in set (0.01 sec)

mysql >alter table test alter index idx_test_c1 invisible;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql >alter table test alter index idx_c2 invisible;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql >show create table test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int NOT NULL,
  `c1` int DEFAULT '0',
  `c2` int NOT NULL DEFAULT '0',
  `c3` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `idx_c2` (`c2`) /*!80000 INVISIBLE */,
  KEY `idx_test_c1` (`c1`) /*!80000 INVISIBLE */,
  KEY `idx_test_c3` (`c3`) /*!80000 INVISIBLE */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
1 row in set (0.00 sec)

3. 查询不可见索引
  • 通过show index 进行查询
#### 查看Visible列值Yes Or No
mysql >show index from test;
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name    | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| test  |          0 | PRIMARY     |            1 | id          | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | YES     | NULL       |
| test  |          1 | idx_c2      |            1 | c2          | A         |           0 |     NULL |   NULL |      | BTREE      |         |               | NO      | NULL       |
| test  |          1 | idx_test_c1 |            1 | c1          | A         |           5 |     NULL |   NULL | YES  | BTREE      |         |               | NO      | NULL       |
| test  |          1 | idx_test_c3 |            1 | c3          | A         |           3 |     NULL |   NULL |      | BTREE      |         |               | NO      | NULL       |
+-------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
4 rows in set (0.00 sec)
  • 通过show creat table 进行查询:
#### 查看索引信息KEY行后面的注释: /*!80000 INVISIBLE */
mysql >show create table test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int NOT NULL,
  `c1` int DEFAULT '0',
  `c2` int NOT NULL DEFAULT '0',
  `c3` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `idx_c2` (`c2`) /*!80000 INVISIBLE */,
  KEY `idx_test_c1` (`c1`) /*!80000 INVISIBLE */,
  KEY `idx_test_c3` (`c3`) /*!80000 INVISIBLE */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
1 row in set (0.00 sec)
  • 通过INFORMATION_SCHEMA.STATISTICS表进行查询:
#### 查询information_schema.statistics表的IS_VISIBLE列值:
select TABLE_SCHEMA,TABLE_NAME,INDEX_SCHEMA,INDEX_NAME,SEQ_IN_INDEX,COLUMN_NAME, IS_VISIBLE from information_schema.statistics where table_schema='rockdb' and table_name='test';
+--------------+------------+--------------+-------------+--------------+-------------+------------+
| TABLE_SCHEMA | TABLE_NAME | INDEX_SCHEMA | INDEX_NAME  | SEQ_IN_INDEX | COLUMN_NAME | IS_VISIBLE |
+--------------+------------+--------------+-------------+--------------+-------------+------------+
| rockdb       | test       | rockdb       | idx_c2      |            1 | c2          | NO         |
| rockdb       | test       | rockdb       | idx_test_c1 |            1 | c1          | NO         |
| rockdb       | test       | rockdb       | idx_test_c3 |            1 | c3          | NO         |
| rockdb       | test       | rockdb       | PRIMARY     |            1 | id          | YES        |
+--------------+------------+--------------+-------------+--------------+-------------+------------+
4 rows in set (0.00 sec)

限制和约束

  • MySQL版本不低于8.0
  • 不可见索引不能用于主键
mysql> ALTER TABLE t2 ALTER INDEX j_idx INVISIBLE;
ERROR 3522 (HY000): A primary key index cannot be invisible.
  • 可以通过系统变量use_invisible_indexes来调整优化器是否使用不可见索引来构建查询执行计划
#### use_invisible_indexes默认为off (优化器将忽略不可见索引)

mysql >show global variables like 'optimizer_switch'\G
*************************** 1. row ***************************
Variable_name: optimizer_switch
        Value: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on
1 row in set (0.00 sec)

#### 默认执行计划会忽略不可见索引
mysql >desc select * from test where c3=5;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test  | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    5 |    33.33 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

#### 通过hint提示来控制系统变量use_invisible_indexes 让SQL执行计划使用不可见索引
mysql >desc select /*+ SET_VAR(optimizer_switch = 'use_invisible_indexes=on') */ * from test where c3=5;
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key         | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test  | NULL       | ref  | idx_test_c3   | idx_test_c3 | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+-------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)

参考文档

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

标签:c3,index,idx,特性,索引,MySQL8.0,test,c2,NULL
From: https://blog.51cto.com/u_13482808/8088486

相关文章

  • AH6971-9V-15v电压升降12V2A芯片解决方案:参数特性和应用领域
    9V-15V升降12V2A芯片解决方案:参数特性和应用领域随着科技的发展,各种智能设备的需求在不断增长,而电源作为智能设备的重要组成部分,其稳定性和效率直接影响着设备的性能。在此背景下,9V-15V升降12V2A芯片解决方案应运而生。参数特性:宽输入电压范围:5V~35V,能够适应多种电源环境。高效......
  • SpringBoot3特性——错误信息Problemdetails
    SpringFramework6实现了HTTPAPI规范RFC7807的问题详细信息。在本文中,我们将学习如何在SpringBoot3RESTAPI(使用SpringFramework6)中处理异常,并使用ProblemDetailsAPI提供错误响应。详见https://www.sivalabs.in/spring-boot-3-error-reporting-using-proble......
  • LCD液晶防干扰段码显示屏驱动芯片VK1C21A/B/C/D/DA/E/EA具备显示效果好,静电耐压高等优
    产品型号:VK1C21A/B产品品牌:永嘉微电/VINKA封装形式:SSOP48/LQFP48可定制裸片:DICE(COB邦定片);COG(邦定玻璃用)产品年份:新年份原厂,工程服务,技术支持! 概述:VK1C21A/B是一个点阵式存储映射的LCD驱动器,可支持最大128点(32SEGx4COM)的LCD屏,也支持2COM和3COM的LCD屏。单片机可通过......
  • 获取摄像头名字和索引
    #pipinstallwmiimportwmidefget_camera_name():camera_names=[]wmi_obj=wmi.WMI()cameras=wmi_obj.Win32_PnPEntity()forcameraincameras:ifcamera.Nameand'camera'incamera.Name.lower():camera......
  • Flutter/Dart第18天:Dart特性之可调用对象
    Dart官方文档:https://dart.dev/language/callable-objects重要说明:本博客基于Dart官网文档,但并不是简单的对官网进行翻译,在覆盖核心功能情况下,我会根据个人研发经验,加入自己的一些扩展问题和场景验证。可调用对象:Dart实例如果实现了call()方法,那么实例就可以像函数那样被调用,这......
  • 重磅更新!Sermant 1.2.0 release版本新特性速览
    10月,Sermant社区正式发布了1.2.0release版本,距离上一次的大版本发布仅三个月。本次新版本带来了多个令人兴奋的新特性,主要包含SermantAgent框架能力的优化和提升以及新增了流量标签透传插件,将极大地提升用户和开发者的体验,帮助大家将Sermant运用到更多的流量治理场景中。(Sermant......
  • Java8新特性
    Stream流可以说是Java8新特性中用起来最爽的一个功能了,有了它,从此操作集合告别繁琐的for循环。但是还有很多小伙伴对Stream流不是很了解。今天就通过本篇,一起深入了解下如何使用它。Java8Stream使用的是函数式编程模式,如同它的名字一样,它可以被用来对集合进行链状流式的操......
  • mysql 索引
    1.索引介绍索引就是一种数据结构,类似于书的目录。意味着以后再查数据应该先找目录再找数据,而不是用翻页的方式查询数据索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。primarykeyuniquekeyindexkey注意:上面三种key前两种除了有加速查......
  • 数据库系列:前缀索引和索引长度的取舍
    数据库系列:MySQL慢查询分析和性能优化数据库系列:MySQL索引优化总结(综合版)数据库系列:高并发下的数据字段变更数据库系列:覆盖索引和规避回表数据库系列:数据库高可用及无损扩容数据库系列:使用高区分度索引列提升性能1背景有时候我们需要在字符类型的字段上建设索引,但是如果......
  • 解锁高效检索技能:掌握MySQL索引数据结构的精髓
    (文章目录)......