MySQL8.0 – 新特性 – Descending Index

MySQL8.0 – 新特性 – Descending Index前言在MySQL8.0之前的版本中,innodbbtree索引中的记录都是严格按照的key的顺序来存储的,但有些时候当我们需要倒序扫描时,效率就会很低。为了解决这个问题,从MySQL8.0版本开始支持在索引Key中倒序存储。你可以按照实际的sql负载来决定如何创建索引,例如你的查询中有Orderbyadesc,basc,就可以创建索引key…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

前言

在MySQL8.0之前的版本中,innodb btree索引中的记录都是严格按照的key的顺序来存储的,但有些时候当我们需要倒序扫描时,效率就会很低。为了解决这个问题,从MySQL8.0版本开始支持在索引Key中倒序存储。你可以按照实际的sql负载来决定如何创建索引,例如你的查询中有Order by a desc, b asc,就可以创建索引key(a desc, b asc),而在8.0之前的版本中则可能需要代价比较大的filesort来进行, 此外逆序扫描Btree也有额外的开销,例如扫描时的page切换,page内扫描,都比正序扫描的开销要大。

本文简单介绍下用法,并分析下对应的代码实现

以下基于当前最新MySQL8.0.13版本

使用

其实对应的语法一直是存在的,只是没有做具体的实现,直到8.0版本才真正实现,使用也很简单,在创建索引时,对索引列加asc/desc关键字,举个简单的例子:

mysql> CREATE TABLE t1 (a INT PRIMARY KEY, b INT, KEY a_idx(a DESC, b ASC));
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT b FROM t1 FORCE INDEX(a_idx);
+------+
| b    |
+------+
|    3 |
|    2 |
|    1 |
+------+
3 rows in set (0.00 sec)

mysql> SELECT b FROM t1 FORCE INDEX(PRIMARY);
+------+
| b    |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

Jetbrains全家桶1年46,售后保障稳定

如上例,可以看到指定不同的索引给出的结果顺序也是不一样的。

mysql> EXPLAIN SELECT * FROM t1 ORDER BY a DESC, b;
+----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key   | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | t1    | NULL       | index | NULL          | a_idx | 9       | NULL |    3 |   100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+-------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

上例中可以看到explain的结果中没有filesort, 而在之前的版本中对于这样的sql是需要进行排序的。

优化器在选择索引时也会考虑到索引列的顺序,目前还有些条件限制:

  • 由于涉及到数据的存储,目前只支持InnoDB
  • Descending index 无法使用change buffer
  • Descneding index不支持fulltext或spatial index, 选择desc关键字会报错
  • GROUP BY不在隐式的保证顺序性,只有明确的指定asc/desc,才去确保顺序

实现

笔者主要工作是在innodb引擎,对server层不甚了解,本文也主要关注innodb的改动。实际上这个特性的改动主要在server层的优化器和执行器,对于innodb来说,尽管数据存储发生了变化,但改动反而很少。

数据词典:
索引上的列属性被持久化到数据词典表(dd::Index)

dd::fill_dd_indexes_from_keyinfo
    dd::fill_dd_index_elements_from_key_parts

key_rec_cmp:
比较的两个key不是大小关系,而是在索引上的前后关系,因此需要考虑键值列上是asc还是desc的
对于range查询,在之前的版本中总是min_Key被传到innodb作为search_tuple来定位btree,但如果是descending index,则需要选择max_key来作为search tuple (ref: SEL_ARG::get_min_flag(), SEL_ARG::get_max_flag(), SEL_ROOT::store_min_key)

InnoDB record compare:
为了支持这个特性,innodb的改动实际上并不大,大部分代码都是没有变化的,这主要是因为InnoDB使用了统一的比较函数来决定key值位置,索引对象传递到底层的比较函数中,以获取是否存在descending column.

相关函数:

cmp_dtuple_rec_with_match_low
cmp_whole_field
cmp_data

判断是否是descending index:
dict_index_has_desc(): 这个函数会扫描索引上所有的列,确保没有desc column, 这个函数看起来有点效率问题,我们可以给dict_index_t加个flag来判断,无需每次遍历

参考文档:

1.官方文档
2. wl#1074: Add Descending indexes support
3.MySQL 8.0 Labs – Descending Indexes in MySQL
4.MySQL 8.0: Descending Indexes Can Speed Up Your Queries
5.相关代码

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/223455.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 数学建模【规划模型–线性规划(整数规划、0-1规划)、非线性规划-附:案例分析、奶制品的生产和销售(详细求解过程)】

    数学建模【规划模型–线性规划(整数规划、0-1规划)、非线性规划-附:案例分析、奶制品的生产和销售(详细求解过程)】4.1数学规划介绍1、数学规划模型的定义2、数学规划模型2.1、企业生产计划3、例1加工奶制品的生产计划3.1、整数规划(IntegerProgramming,简记IP)4、0-1规划模型选课策略5、非线性规划模型5.1、非线性规划5.2、基本概念5.3、算法概述5.4、MATLAB软件求解4.2奶制品的生产和销售1、优化模型和优化软件的重要意义2、优化(Optimization),规划(Programming)3、优化问题的一般形式

  • FPGA和CPLD对比与入门

    FPGA和CPLD对比与入门入门介绍:1、EMP240使用很广泛了,8元一片。EMP240顾名思义具有240个宏单元,或者说240个触发器,或者理解成240个bit的存储单元。2、仿真分2步,写逻辑时用QUARTUS自带的仿真;逻辑写完后,最好用modelsim专门仿真。3、如果你需要100个逻辑单元,实际用的可能是120个,因此要留出20%的余量。4、一个小技巧,针对EPM240和570来说,常用的封装T

  • fsd开机启动_怎么取消开机自动启动软件

    fsd开机启动_怎么取消开机自动启动软件一、vi/etc/rc.d/rc.local添加:/usr/local/nginx/sbin/nginx/usr/bin/fdfs_trackerd/etc/fdfs/tracker.confrestart/usr/bin/fdfs_storaged/etc/fdfs/storage.confrestart二、给rc.local赋可执行权限chmo…

    2022年10月19日
  • JVM 优化实战[通俗易懂]

    JVM 优化实战[通俗易懂]本文讲解了JVM的内存划分和分配策略,并以截图和脚本展示常用可视化和命令行工具的使用方法,完整演示了JVM优化、内存泄露排查、gc.log分析方法等。作者:王克锋 出处:https://kefeng.wang/2016/11/22/java-jvm/ 版权:自由转载-非商用-非衍生-保持署名,转载请标明作者和出处。1GC相关内存1.1内存划分1.1.1堆(Heap)存放 newM…

  • pandas中的drop函数_pandas replace函数

    pandas中的drop函数_pandas replace函数这里写自定义目录标题新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入新的改变我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  • 中介者模式和观察者模式的区别_外观模式和中介者模式异同点

    中介者模式和观察者模式的区别_外观模式和中介者模式异同点中介者模式 Mediator动机模式定义结构要点总结笔记动机在软件构建过程中,经常会出现多个多个对象相互关联交互的情况,对象之间常常会维持一种复杂的引用关系.如果遇到一些需求的更改.这种直接的引用关系将面临不断地变化这种情况下,我们可以使用一个”中介对象”来管理对象间地关联关系,避免相互交互地对象之间地紧耦合引用关系,从而更好地抵御变换模式定义用一个中介对象来封装(封装变化)一系列地对象交互中.中介者使各个对象不需要显式地相互引用(编译时依赖->运行时依赖),从而使其耦合松散(管理变化),而

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号