Innodb:使用索引避免排序后DESC和ASC的区别

简介: Innodb:使用索引避免排序后DESC和ASC的区别

一、问题由来

这个问题是朋友提出的,大概意思就是说,Innodb 的记录中只会包含rec next的位置,那么块内部反向扫描如何完成的,比如使用索引避免排序后的DESC操作。实际上这个问题可以简单描述为Innodb 块内部是单向链表,如果要反向扫描那么是如何的。


二、相关接口

实际上对于正向和反向扫描记录使用的方法并不一致,大概的接口为:

正向:page_rec_get_next_low

这里很容易看出就是通过rec next位置来确认下一条记录,这非常容易也非常简单,代价极小。

反向:page_rec_get_prev_const

这个函数实际上可以简单的看一下就知道获取prev(上一条记录)就复杂了一些,它通过slot来进行定位,然后进行循环比对来获取上一条记录。


三、反向(DESC)大概获取流程

首先我们要清楚slot是干什么的,实际上在定位数据的时候会先定位到slot,然后再在slot内部做一个二分法。slot对于记录来讲是有序的,即逻辑上是顺序的(非物理顺序)。一个slot为2字节存储的是对应记录的偏移量,而一个slot最多包含8条记录,关于slot的讲解很多书籍都有说明,不再赘述。

好了我们假设上一次读取到的prev row = G,而slot内部包含了A、B、C、D、E、F、G 7条记录。

第一步定位到slot的开头即记录A的位置。


LOOP:设置本次 prev row = A
通过A的rec next位置获取下一条记录 B
是否 B == G
{如果是则记录prev row= A 停止循环}
否则
{继续循环,下一次循环prev row = B }

LOOP:设置本次 prev row = A

通过A的rec next位置获取下一条记录 B

是否 B == G

{如果是则记录prev row= A 停止循环}

否则

{继续循环,下一次循环prev row = B }

这个循环一直要持续到 prev row = F ,即 G == G 成立才结束。循环次数为6次。

可以看到这样上一条记录就找到了,不过看起来代价比ASC方式大了很多很多。


四、如何避免

MySQL 8的降序索引值得拥有。或者规避这个问题。


五、debug栈帧和结果

1、DESC 多次循环

image.png

2、调用栈帧

image.png

            </div>
相关文章
|
存储 安全 关系型数据库
后端技术:构建高效稳定的现代Web应用
【10月更文挑战第5天】后端技术:构建高效稳定的现代Web应用
676 1
|
机器学习/深度学习 自然语言处理 并行计算
[Bert]论文实现:BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
[Bert]论文实现:BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
590 1
|
人工智能 IDE 测试技术
探索软件测试的自动化之旅
【7月更文挑战第31天】在软件开发领域,自动化测试已成为提升效率、确保质量的关键工具。本文将介绍如何通过Python和Selenium库实现一个简单的自动化测试框架,旨在帮助读者理解自动化测试的基本概念及其实现方式。我们将从环境搭建开始,逐步深入到编写测试用例,最后探讨如何运行和分析测试结果。
59 2
|
存储 Swift
Swift之struct二进制大小分析
【7月更文挑战第18天】Swift 中 `struct` 的二进制大小分析: `struct` 作为值类型, 其内存布局和大小由成员变量决定。基本类型如 `Int`, `Double`, `Bool` 存储大小固定; 复合类型如数组大小取决于元素数量及类型。示例 `struct` 包含 `Int`, `Double`, `Bool`, 和 `[String]`。`Int` 和 `Double` 各占 8 字节, `Bool` 占 1 字节, 数组大小根据字符串存储开销变化。还需考虑内存对齐以优化访问效率。综上, 分析 `struct` 大小需考量多种因素。
159 1
|
SQL 存储 关系型数据库
数据库学习方法
【8月更文挑战第25天】数据库学习方法
190 0
|
XML 安全 Java
Spring的SpEL表达式
SpEL(Spring Expression Language)是支持运行时计算和操作对象的表达式语言,它和传统的EL表达式语法相似,还提供了方法调用,字符串模板等更强大的功能。
1191 4
|
Linux Shell 文件存储
[Bytes,Network,eth0,网络数据,Linux]如何从Linux系统中获取带宽、流量网络数据
  Linux中的网络数据提取   在Linux系统中我们可以从/proc 目录里来获取相应的数据并进行处理。   让我们来看下网络相关的/proc/net/dev
312 0
|
Oracle 关系型数据库 数据库