19 视图定义 union 是根据第一个 select 字段列表顺序,来进行 merge 的

2023-09-15 09:48:55

前言

这个问题主要是 在之前存在这样的一个问题, 在生产环境上面 

按照 我的直观理解, mysql 应该是根据 key 进行 merge, 所以 select 的顺序应该是 “不重要”??, 但是 结果我理解错了

然后 线上的查询也出现了问题, 发现很奇怪的问题, 明明 key01 列 是 id, 但是有一部分 key01 是 field1, 然后 进而 产生了业务上面的查询问题 

这里从 mysql 的查询开始回溯这里的整个流程 

select id as key01, field1 as key02 from tz_test

union

select field1 as key02, id as key01 from tz_test_02

 

测试表结构信息如下 

CREATE TABLE `tz_test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `field1` varchar(12) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3333343 DEFAULT CHARSET=utf8

 

 

将数据从 rec 转换为 mysql_rec

这里的处理是将具体的 rec 中的给定的字段复制到 mysql_rec 中存储 

4f9cba1c226e4ebc87784a66e463cbd3.png

 

外层是遍历字段, 遍历完字段之后 需要的字段就已经转换到了 mysql_rec 中 

a7fdfa60db7944cfa6a4bba49ea1dcc7.png

 

mysql_rec 中的顺序和 select 中的顺序无关 

rec 的数据部分结构如下 

05d44d9249cf45aa8dd574243930d409.png

 

mysql_rec 的结构如下, prebuilt->mysql_template[i] 中存储的是响应的字段的元数据 

6b570bbe52c04acea275511ca76d22ea.png

 

 

将数据更新到 Field->ptr 中 

初始化 read_record 的地方 

这里初始化的 record 为 table->record[0]

再看 qeb_tab->fields 中的信息可以看到 ptr 已经设置好了, 可以推断出 ptr 是在之前就已经更新好了的, 这需要回溯到 table->record 的初始化相关 

9da64921c49b4508b04124be4399b63f.png

 

qup_tab 中的 fields, all_fields 初始化如下 JOIN.fields_list, all_fields

2bf9bc457cd14f08a458b250ab0624d9.png

join 的 fields_list 来自于 select_lex

75e3584a20f946018e86daeac2ee8aae.png

 

解析来源 sql 的时候从 sql 中解析出了 字段名称, 但是 尚未填充 TABLE, FIELD 等等相关结构 

1b3b48f79b304f369b843e9020d47a8b.png

select_lex 中的各个字段初始化如下, 主要是通过 find_field_in_tables 中查询的 

70fafea45da24803ac7dbefe699760d0.png

 

比如我们这里 tz_test 表, 字段的 lookup 是通过遍历字段 然后 比较字段名来确认的

其他的信息 我们不在赘述

1dd73ad6102b41a5806ab27db0c2bfd7.png

 

 

TABLE 的 record[0] 的初始化, 和相关的 Field 的初始化的流程了 

默认情况下 mysql 目标表的加载是懒加载的

然后这里从 frm 中读取相关的元数据, 加载到 服务的内存中

这里是创建各个 Field

6fdac05ed9254d54b4a474d873ffdf4a.png

 

然后给定的字段的 ptr 是初始化为 table->record[0] 加上一个字段偏移 

所以说字段布局已经在创建表 的时候已经确定好了

这就是为什么 上面服务器将数据从 rec 中转换到 mysql_rec 中 

然后后面基于 Item, Field 可以直接读取到给定的字段的值的原因了 

65683816d1ec4d1f9700b1c4fe102a0b.png

 

 

union表 的结果查询

union 这边是通过一个临时表来进行的数据查询 

子查询1 将查询结果 “写入” 临时表union

子查询2 将查询结果 “写入” 临时表union

然后 最终一起查询 临时表union, 然后再将相应的数据 响应给客户端

 

迭代具体的记录信息的地方如下 

7f225df830e14afdbe3899f4e8df6070.png

 

这里拷贝的 rec 记录信息如下, 这是 临时表 的 TABLE->record[0]

然后这里的存储方式是按照 mysql_rec 的方式来存储, 然后使用 Field_xxx::val_str 来读取给定的 buf 的数据, 然后之后通过  

b8b392685eb0472e8041802f69405212.png

 

临时表union 的 key01 字段如下, 可以看到 ptr 是在 TABLE->record[0] 的区间内 

af23e3254dcd417fb7ef5e6ad42c957c.png

 

临时表union 的 key02 字段如下, 可以看到 ptr 是在 TABLE->record[0] 的区间内 

decc55f7b7174fd290d9fb9c1e4e90ea.png

 

表中的数据通过 Field_varstring::val_str 来解析给定的 mysql_rec 的数据  

f76f8503b9464c708c66e70964384d3c.png

 

将待输出字符串输出到输出缓冲区, 这里记录了 长度 和 具体的字符信息 

这里待输出字符串为 “7777777”, 输出一个字节长度 07, 接着七个字节为 ‘7’

57ca22420c144d61a28f0aa628b420a0.png

 

输出缓冲区待写出数据如下, 一个字节长度 0x07, 七个字节字符信息 “0x32323232323232”

3b94bb87b4af48c0baa209636b760ccb.png

 

 

union表 的数据来源 

这是从 “select id as key01, field1 as key02 from tz_test” 查询出来的第一条记录 

然后 将其写出到 union表 

96819ec9baac4596856c9df328dddc82.png

 

tz_test 查询出来的第一条记录 {id : 1111111, field1 : 12 }

1353256196664fc79758ae19f7984a3a.png

 

将查询出来的第一条记录的 id 转换为 Field_str, 存储起来 

2375e7660e584900a3157dac065b21aa.png

将 TABLE->record[0] 的数据 “持久化” 起来, 这里是放到 ha_heap 的固定的空间  

92384090901f44639b16084e910ca266.png

 

tz_test_2 的查询结果做数据转换的时候, 可以看到的是 field1 存储到的是 key01 字段 

a038748e51504f32bf9d60169ebaf317.png

 

这个字段是顺序如下, key01, key02 是取自 union 的第一个查询, 根据这个字段列表创建的临时表 

然后 “select field1 as key02, id as key01 from tz_test_02” 的查询结果按照 列的顺序 分别保存到对应的列, 然后 后面 table->file->ha_file_write 写出到 union表 

219a15dc3db24b3a824ee30154c1bb31.png

 

 

union表 的创建

创建临时表的地方如下, 在 handle_query 的地方, 传入的 column_types 列表为 key01, key02

c3c3d932124c48ca944639b130f1397b.png

 

传入的 column_types 外部的初始化如下, 获取第一个查询 选择列 列表, 作为临时表的字段列表 

2cc6368d03574377b21ae3219fcadf33.png

 

在执行 join 之前, 创建了 结果的临时表

然后 后面查询迭代使用的字段列表, 都是使用的 这里创建的字段列表

21f0ebe4c70f4a53bd4cf83554cbf383.png

 

 

 完

 

 

 

更多推荐

9 种方法使用 Amazon CodeWhisperer 快速构建应用

AmazonCodeWhisperer是一款很赞的生成式人工智能编程工具。自从在工作中使用了CodeWhisperer,我发现不仅代码编译的效率有所提高,应用开发的工作也变得快乐起来。然而,任何生成式AI工具的有效学习都需要初学者要有接受新工作方式的心态和意愿。AmazonCodeWhispererAICodeGene

一篇关于vue的入门的详细介绍

目录一.介绍二.库和框架的区别三.什么是MVVM模式四.实例4.1.Vue开发示例4.2.双向数据绑定4.3.生命周期好啦,今天的分享就到这了,希望能够帮到你呢!😊😊一.介绍Vue.js是一种流行的JavaScript框架,用于构建用户界面。它被设计为一个渐进式框架,可以逐步应用到现有项目中,也可以作为一个完整的单

【JVM】Java类的加载机制!

一、类的生命周期类加载过程包含:加载、验证、准备、解析和初始化,一共包括5个阶段。(1)加载:简单来说就是将java类的字节码文件加载到机器内存中。在加载类时,Java虚拟机必须完成以下3件事情:通过类的完全限定名称获取定义该类的二进制字节流。将该字节流表示的静态存储结构转换为Metaspace元空间区的运行时存储结构

科锐逆向第二阶段(一)SDK

基本概念什么是SDKSDK是软件开发工具包(SoftwareDevelopmentKit)的缩写。它是一个集成了软件开发所需工具、库文件、示例代码和文档等资源的软件包。SDK通常由软件开发公司或平台提供,旨在帮助开发人员构建、测试和部署特定类型的应用程序、库或服务。它提供了一套开发工具,使开发人员能够利用平台或框架的功

idea把项目打成jar包步骤详解

最近产品需要预研一个小功能,开始后在本地开发测试好之后,需要打成jar提供出去,今天弄完了,决定把这个步骤记录下来,便于以后轻车熟路。打成jar要有mian方法的入口,所以我们在代码中需要定义一个main方法,然后通过这个main方法调用我们的核心逻辑代码。下面是我的代码示例:publicstaticvoidmain(

基于微信小程序的图书管理系统设计与实现(源码+lw+部署文档+讲解等)

前言💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗👇🏻精彩专栏推荐订阅👇🏻2023-2024年最值得选的微信小程序毕业设计选题大全:100个热门选

使用 OpenWRT 设置 Banana Pi BPI-R3开源硬件路由器

这里介绍如何使用pfSense将ZimaBoard216设置为防火墙的链接。我们正在为小型板计算机建立一个专用网络,这样当我开始教授Linux时,我就可以显示和共享它的IP。现在为我的网络设置一条到pfSense后面的路由。这是为了提供另一个级别的安全性。我有两台Banana-Pi路由器1)Banana-PiR2Pro

【案例教学】华为云API图引擎服务 GES的便捷性—AI帮助快速处理图片小助手

云服务、API、SDK,调试,查看,我都行阅读短文您可以学习到:人工智能AI快速处理图片1IntelliJIDEA之API插件介绍API插件支持VSCodeIDE、IntelliJIDEA等平台、以及华为云自研CodeArtsIDE,基于华为云服务提供的能力,帮助开发者更高效、便捷的搭建应用。API插件关联华为云服务下

虹科教您 | 可实现带宽计量和延迟计算的时间敏感网络测试工具RELY-TSN-LAB操作指南与基本功能测试

1.RELY-TSN-LAB产品概述时间敏感网络(TSN)能够合并OT和IT世界,这将是真正确保互操作性和标准化的创新性技术。这项技术的有效开发将显著降低设备成本、维护、先进分析服务的无缝集成以及减少对单个供应商的依赖。为了在这些网络中实现确定性,需要控制连接到网络的设备的延迟和带宽,并预测其在拥堵和错误情况下的行为。

利用Windows搭建Emby媒体库服务器,轻松实现无公网IP的远程访问

文章目录1.前言2.Emby网站搭建2.1.Emby下载和安装2.2Emby网页测试3.本地网页发布3.1注册并安装cpolar内网穿透3.2Cpolar云端设置3.3Cpolar内网穿透本地设置4.公网访问测试5.结语1.前言在现代五花八门的网络应用场景中,观看视频绝对是主力应用场景之一,加上移动网络技术的发展,随时

【RNN从入门到实战】GRU入门到实战——使用GRU预测股票。

摘要GRU是LSTM网络的一种效果很好的变体,它较LSTM网络的结构更加简单,而且效果也很好,因此也是当前非常流形的一种网络。GRU既然是LSTM的变体,因此也是可以解决RNN网络中的长依赖问题。在LSTM中引入了三个门函数:输入门、遗忘门和输出门来控制输入值、记忆值和输出值。而在GRU模型中只有两个门:分别是更新门和

热文推荐