首页 > 数据库 >MySQL8.0索引新特性

MySQL8.0索引新特性

时间:2024-07-09 13:57:26浏览次数:22  
标签:index 特性 查询 索引 MySQL8.0 MySQL 隐藏 ts1

文章目录



在这里插入图片描述

在这里插入图片描述


1 支持降序索引

image.png
举例:分别在MySQL 5.7版本和MySQL 8.0版本中创建数据表ts1,结果如下:

CREATE TABLE ts1(
  a int,
  b int,
  index idx_a_b(a,b desc)
);

在MySQL 5.7版本中查看数据表ts1的结构,从结果可以看出,索引仍然是默认的升序。

在MySQL 8.0版本中查看数据表ts1的结构,从结果可以看出,索引已经是降序了。下面继续测试降序索引在执行计划中的表现。

分别在MySQL 5.7版本和MySQL 8.0版本的数据表ts1中插入800条随机数据,执行语句如下:

DELIMITER //
CREATE PROCEDURE ts_insert()
BEGIN
  DECLARE i INT DEFAULT 1;
  WHILE i < 800
  DO
    insert into ts1 select rand()80000,rand()80000;
    SET i = i + 1;
  END WHILE;
  commit;
END //
DELIMITER ;

# 调用
CALL ts_insert();


在MySQL 5.7版本中查看数据表ts1的执行计划,结果如下:

EXPLAIN SELECT * FROM ts1 ORDER BY a,b DESC LIMIT 5;

从结果可以看出,执行计划中扫描数为799,而且使用了Using filesort。
提示 Using filesort是MySQL中一种速度比较慢的外部排序,能避免是最好的。多数情况下,管理员
可以通过优化索引来尽量避免出现Using filesort,从而提高数据库执行速度。

在MySQL 8.0版本中查看数据表ts1的执行计划。从结果可以看出,执行计划中扫描数为5,而且没有使用
Using filesort。
注意 降序索引只对查询中特定的排序顺序有效,如果使用不当,反而查询效率更低。例如,上述
查询排序条件改为order by a desc, b desc,MySQL 5.7的执行计划要明显好于MySQL 8.0。

将排序条件修改为order by a desc, b desc后,下面来对比不同版本中执行计划的效果。 在MySQL 5.7版本
中查看数据表ts1的执行计划,结果如下:

EXPLAIN SELECT * FROM ts1 ORDER BY a DESC,b DESC LIMIT 5;

在MySQL 8.0版本中查看数据表ts1的执行计划。
从结果可以看出,修改后MySQL 5.7的执行计划要明显好于MySQL 8.0。

2 隐藏索引

在MySQL 5.7版本及之前,只能通过显式的方式删除索引。此时,如果发现删除索引后出现错误,又只能
通过显式创建索引的方式将删除的索引创建回来。如果数据表中的数据量非常大,或者数据表本身比较
大,这种操作就会消耗系统过多的资源,操作成本非常高。

从MySQL 8.x 开始支持 隐藏索引(invisible indexes) ,只需要将待删除的索引设置为隐藏索引,使
查询优化器不再使用这个索引(即使使用force index(强制使用索引),优化器也不会使用该索引),
确认将索引设置为隐藏索引后系统不受任何响应,就可以彻底删除索引。 这种通过先将索引设置为隐藏索
引,再删除索引的方式就是软删除 。

同时你想验证某个索引删除之后的 查询性能影响就可以暂时先隐藏起来。

注意:主键不能被设置为隐藏索引。当表中没有显示主键时,表中的第一个唯一非空索引会成为隐式主键,也不能设置为隐藏索引。

image.png

  1. 创建表时直接创建

在MySQL中创建隐藏索引通过SQL语句INVISIBLE来实现,其语法形式如下:

CREATE TABLE tablename(
propname1 type1[CONSTRAINT1],
propname2 type2[CONSTRAINT2],
……
propnamen typen,
INDEX [indexname](propname1 [(length)]) INVISIBLE
);

上述语句比普通索引多了一个关键字INVISIBLE,用来标记索引为不可见索引。

  1. 在已经存在的表上创建
    可以为已经存在的表设置隐藏索引,其语法形式如下:
CREATE INDEX indexname
ON tablename(propname[(length)]) INVISIBLE;
  1. 通过ALTER TABLE语句创建
    语法形式如下:
ALTER TABLE tablename
ADD INDEX indexname (propname [(length)]) INVISIBLE;
  1. 切换索引可见状态 已存在的索引可通过如下语句切换可见状态:
ALTER TABLE tablename ALTER INDEX index_name INVISIBLE; #切换成隐藏索引
ALTER TABLE tablename ALTER INDEX index_name VISIBLE; #切换成非隐藏索引

如果将index_cname索引切换成可见状态,通过explain查看执行计划,发现优化器选择了index_cname索
引。
注意 当索引被隐藏时,它的内容仍然是和正常索引一样实时更新的。如果一个索引需要长期被隐
藏,那么可以将其删除,因为索引的存在会影响插入、更新和删除的性能。

通过设置隐藏索引的可见性可以查看索引对调优的帮助。

  1. 使隐藏索引对查询优化器可见
    在MySQL 8.x版本中,为索引提供了一种新的测试方式,可以通过查询优化器的一个开关
    (use_invisible_indexes)来打开某个设置,使隐藏索引对查询优化器可见。如果 use_invisible_indexes
    设置为off(默认),优化器会忽略隐藏索引。如果设置为on,即使隐藏索引不可见,优化器在生成执行计
    划时仍会考虑使用隐藏索引。


(1)在MySQL命令行执行如下命令查看查询优化器的开关设置。

mysql> select @@optimizer_switch \G

在输出的结果信息中找到如下属性配置

use_invisible_indexes=off

此属性配置值为off,说明隐藏索引默认对查询优化器不可见。

(2)使隐藏索引对查询优化器可见,需要在MySQL命令行执行如下命令:

mysql> set session optimizer_switch="use_invisible_indexes=on";
Query OK, 0 rows affected (0.00 sec)

SQL语句执行成功,再次查看查询优化器的开关设置。

mysql> select @@optimizer_switch \G
*************************** 1. row ***************************
@@optimizer_switch:
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_co
st_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_ind
exes=on,skip_scan=on,hash_join=on
1 row in set (0.00 sec)

此时,在输出结果中可以看到如下属性配置

use_invisible_indexes=on

use_invisible_indexes属性的值为on,说明此时隐藏索引对查询优化器可见。

(3)使用EXPLAIN查看以字段invisible_column作为查询条件时的索引使用情况。

explain select * from classes where cname = '高一2班';

查询优化器会使用隐藏索引来查询数据。

(4)如果需要使隐藏索引对查询优化器不可见,则只需要执行如下命令即可。

mysql> set session optimizer_switch="use_invisible_indexes=off";
Query OK, 0 rows affected (0.00 sec)

再次查看查询优化器的开关设置

mysql> select @@optimizer_switch \G

此时,use_invisible_indexes属性的值已经被设置为“off”。


MySQL8忘记密码:https://blog.csdn.net/weixin_44714097/article/details/127055715



在这里插入图片描述

标签:index,特性,查询,索引,MySQL8.0,MySQL,隐藏,ts1
From: https://blog.csdn.net/aliyunyyds/article/details/140285146

相关文章

  • 【JDK8】新特性(二)
    6.StreamAPIJava8的两个重大改变,一个是Lambda表达式,另一个就是StreamAPI表达式。Stream是java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的査找、过滤、筛选等操作.6.1为什么使用stream流当我们需要对集合中的元素进行操作的时候,除了必需的添加、删除、获取......
  • MySQL 进阶(二)【索引详解】
    前言    程序员避不开和数据库打交道,大数据更是如此,不管是MySQL、Oracle、SQLServer这些OLTP数据库,还是Greeplum、StarRocks、Hive、SparkSQL、FlinkSQL、ClickHouse等OLAP数据库,SQL都是最基础最重要的能力,数据库知识也是每一个程序员必备的知识。  ......
  • 自建搜索引擎-基于美丽云
    Meilisearch是一个搜索引擎,主程序完全开源,除了使用官方提供的美丽云服务(收费)进行对接之外,还可以通过自建搜索引擎来实现完全独立的搜索服务。由于成本问题,本博客采用自建的方式,本文就讲讲怎么搭建。‍本文主要参考:meilisearch全接入指南|二丫讲梵:讲了怎么使用官方提供的......
  • docker安装mysql8.0.23
    拉取镜像dockerpullmysql:8.0.23创建挂载文件mkdir-p/home/docker/mysql/confmkdir-p/home/docker/mysql/datamkdir-p/home/docker/mysql/logcd/home/docker/mysql/conftouchmy.cnf编辑my.cnfvimy.cnf内容如下:default-character-set=utf8[mysql]defa......
  • HTTP协议30 丨 2特性概览
    刚结束的“安全篇”里的HTTPS,通过引入SSL/TLS在安全上达到了“极致”,但在性能提升方面却是乏善可陈,只优化了握手加密的环节,对于整体的数据传输没有提出更好的改进方案,还只能依赖于“长连接”这种“落后”的技术(参见第17讲)。所以,在HTTPS逐渐成熟之后,HTTP就向着性能方面......
  • HTTP协议27丨更好更快的握手:TLS1.3特性解析
    上一讲中我讲了TLS1.2的握手过程,你是不是已经完全掌握了呢?不过TLS1.2已经是10年前(2008年)的“老”协议了,虽然历经考验,但毕竟“岁月不饶人”,在安全、性能等方面已经跟不上如今的互联网了。于是经过四年、近30个草案的反复打磨,TLS1.3终于在去年(2018年)“粉墨登场”,再......
  • ElasticSearch系列---【在已有索引中添加新的字段】
    1.问题描述消费kafka的数据,写入es,为了查看推送时间和消费时间的时间差值,我们需要在原有的es索引core_pri_flow_202405中添加新字段produce_time和create_time。2.直接使用devtools添加新字段#使用Easy-Es框架,实体类中添加字段@IndexField(value="produce_time",fieldType=Fie......
  • Java [ 基础 ] Java 8以上新特性 ✨
    ✨探索Java基础Java8以上新特性✨Java8及以上的新特性Java8引入了一些重大更新和新特性,这些特性极大地增强了Java的功能和性能。随着Java9、10、11、12及以后的版本发布,Java持续引入更多的改进和新功能。本文将介绍Java8及以上版本的一些关键新特性。Java8新特......
  • Mysql中索引的分类、增删改查与存储引擎对应关系
    场景Mysql中存储引擎简介、修改、查询、选择:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/140269624上面介绍Mysql的存储引擎。下面介绍索引的分类和使用。注:博客:https://blog.csdn.net/badao_liumang_qizhi实现Mysql中索引的分类1、普通索引和唯一索引......
  • RAG知识库之多表示索引
          在朴素RAG中通常会对文档、文本进行分块后进行文档嵌入,对所有文件、文本都没有经过采用Chunk方法可能有时候效果不是和好,尽管有着各种分块策略有针对大文件的、针对小文件的策略,但都难免可能会造成上下文语义丢失。      分块通常有两个非常重要的参数chunk_si......