2023-06-02 stonedb-修改包含内连接的嵌套外连接-问题反思

news2024/12/25 9:08:26

摘要:

最近在搞一个列存储引擎的包含内连接的嵌套外连接过慢的问题, 连接执行过慢的原因分析见此前的博客分析, 虽然逻辑很绕, 但是也不是无法分析.

更麻烦的问题在于修改查询计划, 让其能按照代价更小的方式正确的执行.

遇到的问题比我在修改查询计划前设想的更为棘手, 本文做下记录.

包含内连接的嵌套外连接执行过慢的问题原因分析:

  1. 最关键的问题出在内连接生成的中间结果的大小上
  2. 在mysql/sql层, 将内连接的条件全部上推, 导致内连接没有过滤条件,结果就是内连接的结果是R与S的叉乘
  3. 外连接U与(R和S的叉乘)做运算, 现在条件全部集中在外连接这一层, 连接的时间复杂度达到了惊人的 U 连接 (R叉乘S)
  4. 外连接的执行策略为散列连接, 对U做构建散列, 使用R叉乘S的结果集做探测集
  5. 虽然在逻辑理解上可以认为是对U做构建散列,但是这里的散列是一种连续地址的空间, 每次查找元素, 时间复杂度并不是槽位映射的O(1), 而是要从头遍历整个连续地址空间的O(n)
  6. 所以整个的包含内连接的嵌套外连接的执行时间复杂度可以这么理解
    1. 对外表U构建散列, 耗时为 M(U)
    2. 使用R叉乘S的结果集做探测集, 设散列探测单个元素的时间复杂度为O(1), 这里先忽略线性地址空间的O(n)的复杂度导致的问题复杂性的升级, 那么探测过程的耗时可以理解为 N(R*S)
    3. 总的耗时可以理解为 M(U) + N(R*S)
  7. 在执行的过程中, 最大的问题便是R*S的结果集过大, 注意这里是完整的R和S的叉乘, 中间结果并没有经过条件的过滤
  8. 那么解决问题的思路, 便是顺着减少R与S的叉乘的结果集入手, 这里有两种不同的思路
    1. 停止将内连接的条件上推, 在执行R与S的内连接时, 对中间结果进行过滤
    2. 基于外连接与内连接的集合论与包的理论, 将U外连接(R内连接S), 做集合的分解, 处理成 U连接R + U 连接S

优化R叉乘S的中间结构的思路分析:

一. 结合集合论与包的理论, 分解U外连接(R内连接S)

  1. 这种做法在理论上具有直观性
  2. 所涉及的逻辑计划和物理计划所要修改的地方过多, 无法保证解决掉每个场景上可能出现的问题
  3. 在可以预料到的时间内无法做到bug zero

二. 不对内连接的条件上推, 对内连接的结果执行过滤并直接物化

  1. 在设计层面所要做的修改更少, 注意只是理论上的, 实际要要做的工作取决于对当前列存储引擎的理解的程度
  2. 对查询序列做的修改的过程中, 保持了直观性, 而避免了相对而言过多的抽象性, 也就是每一步的处理都保持了所见即所得, 这样有助于定位过程中出现的问题, 其实本质上还是因为对当前代码的驾驭力不足以做更为剧烈的改动
  3. 综上, 本质还是对连接处理的驾驭力的问题
  4. 而所谓驾驭力的体现上, 就是对当前列存储引擎对于将mysql/sql层的查询树的结构, 转换为自己的查询序列的结构并执行的过程,这中间所涉及的细节的驾驭的问题

对内连接不做条件上推并直接物化所遇到的问题:

虽然相对来说, 对内连接做直接物化减少中间结果集的大小, 所遇到的问题更少, 但是在具体处理的时候, 还是遇到了不少问题:

  1. 修改逻辑计划中包含内连接与外连接的表之间的关系倒是简单,因为虽说这种关系是一种递归, 但是毕竟非常直接, 不存在更多的理论上的盲区
  2. 直接修改mysql/sql层的内连接条件上推的处理后, 列存储引擎对于该查询树的处理存在问题, 无法正确的识别, 表现在构建cond时存在表关系依赖的失败
  3. 当修改完列存储的逻辑执行序列后, 开始遇到一系列关于表之间关系, 条件与表之间关系的问题
  4. 列存储引擎在逻辑执行序列的预处理阶段, 发生外连接的位图的识别的错误
  5. 这里值得注意, 列存储引擎的查询执行序列, 使用了大量对于表和元素的重构的处理, 类似于monetdb中的BAT的执行序列, 但是monetdb的BAT执行更为严格, 每一步仅仅为最原始的执行步骤, 而列存储引擎的查询执行序列, 虽然执行的单元也是以列为中心, 但是却是以关系为出发点, 条件之间的组合与表之间的关系更为自由
  6. 在执行条件过滤的时候, 会对查询执行序列做动态的修改, 可以理解成将一部分的物理优化延迟到了具体执行该查询序列之前, 包括:
    1. 根据空值拒绝将外连接转换为内连接
    2. 对一些可直接拿到结果的连接的集合进行直接物化
    3. 这个过程中会对表之间的关系, 以及条件与表的关系进行处理, 当对包含内连接的嵌套外连接的查询执行序列做修改后, 相关的关系被破坏, 根本原因还是对列存储引擎的执行的细节理解的不够深刻
  7. 在散列连接的散列构建阶段, 会对外连接与内连接的表之间的关系做处理
    1. 可以理解为散列连接的预处理阶段, 对小表进行散列构建
    2. 这个过程会继续使用表之间的位图关系, 进行表间关系与条件关系的检测处理
    3. 此过程发生的最明显的问题便是存在外连接或内连接的表位图占位的丢失导致检测失败

一些分析草图:

 

参考:

MySQL :: MySQL 5.7 Reference Manual :: 8.2.1.7 Nested Join Optimization

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/614166.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python循环次数:实现高效编程的关键

Python循环次数:实现高效编程的关键 在编写Python程序时,循环次数是一个经常需要关注的问题。循环次数过多会导致程序执行效率低下,甚至可能引起性能问题。因此,如何控制循环次数成为实现高效编程的关键。本文将介绍Python中循环…

chatgpt赋能python:Python如何实现将数据结果导出

Python如何实现将数据结果导出 在Python编程中,我们经常需要将代码运行的结果导出保存在文件中,或在其他程序中使用。下面我们将介绍Python中几种将数据结果导出的方法。 方法一:使用文件输出 使用Python内置的open方法来打印输出的结果到…

【C++】类和对象 - 对象特性 - 构造函数和析构函数,函数分类及调用,拷贝构造函数调用时机,构造函数调用规则,深浅拷贝,初始化列表,类对象作为类成员

No.Contents1【C】基础知识 - HelloWorld,注释,变量,常量,关键字,标识符2【C】数据类型 - 整型,sizeof,实型,字符型,转义字符,字符串类型,布尔类型…

chatgpt赋能python:Python版本更新:为什么你应该及时升级

Python版本更新:为什么你应该及时升级 作为一名有10年Python编程经验的工程师,我深刻理解Python版本更新的重要性。在这篇文章中,我将向你介绍Python版本更新的背景和原因,并告诉你如何及时升级Python的版本以保持你的代码的安全…

由 Direct buffer memory 引发的附件下载优化方案

文章目录 前言一、Direct buffer memory1.1 原因分析1.2 解决方案 二、附件下载2.1 问题分析2.2 解决方案2.2.1 本地下载2.2.1 minio下载 前言 本地上传大文件内存溢出 Direct buffer memory附件下载服务端传流给前端需要将流缓存完毕才可以下载,导致大文件下载系统…

浏览器的渲染原理

网页的解析过程 ◼ 常见的浏览器内核有  Trident ( 三叉戟):IE、360安全浏览器、搜狗高速浏览器、百度浏览器、UC浏览器;  Gecko( 壁虎) :Mozilla Firefox;  Presto&#xff…

chatgpt赋能python:Python散点图连接成光滑曲线的技巧

Python散点图连接成光滑曲线的技巧 Python是一种功能强大的编程语言,广泛用于数据科学、机器学习、Web开发和自动化等领域。在数据可视化中,散点图是一种非常重要的图表类型,用于显示两个变量之间的关系。然而,有时散点图可能过于…

Linux 可视化管理-webmin 和 bt 运维工具

Linux 可视化管理-webmin 和bt 运维工具 webmin 基本介绍 Webmin 是功能强大的基于Web 的Unix/linux 系统管理工具。管理员通过浏览器访问Webmin 的各种管理功能并完成相应的管理操作。除了各版本的linux 以外还可用于:AIX、HPUX、Solaris、Unixware、Irix 和Fre…

freeRTOS学习(四)

队列管理 队列提供了任务到任务、任务到中断和中断到任务的通信机制。 队列的特征 数据存储 队列可以保存有限数量的固定大小的数据项。一个队列所能容纳的最大条目数称为它的长度。每个数据项的长度和大小都在创建队列时设置。 队列通常用作先进先出(FIFO&…

【利用AI让知识体系化】常见的移动端适配知识

I. 引言 A. 移动设备的普及度 移动设备的普及度近年来持续攀升,据统计,截至2021年,全球手机用户数量已达51.98亿,而智能手机的普及率则已经超过了70%,成为人们生活中最为重要和常用的工具之一。 同时,平…

chatgpt赋能python:Python如何更改?

Python如何更改? 如果您想成为一名成功的Python程序员,那么您需要知道如何更改Python代码。在这篇文章中,我们将介绍Python如何更改,并提供一些实用的技巧和建议来使您的编码更加高效和有用。 什么是Python? Python…

chatgpt赋能python:Python如何填充颜色

Python如何填充颜色 Python是一种简单易学但功能丰富的编程语言,被广泛用于各种开发领域。其中填充颜色是Python中的一个非常重要的功能,在很多项目中都会经常用到。本文将介绍Python如何填充颜色,让你快速上手。 什么是填充颜色 填充颜色…

Python matplotlib库的使用

目录 画图的两种基本方式: 隐藏边框: 隐藏坐标系 设置网格线 共享坐标轴 双坐标轴 设置坐标轴标签及刻度字体大小 设置坐标轴标签据离坐标轴距离 画点与线 标注文字 画不同大小的多个坐标系 调节子图间距 导入库: import matplotl…

【JavaSE】Java(五十):核心要点

文章目录 1. JDK 和 JRE 有什么区别2. \和 equals 的区别3. final 在java中有什么作用4. Java中的Math() 类有哪些常用方法5. String 属于基础数据类型吗? 1. JDK 和 JRE 有什么区别 JDK(Java Development Kit)和 JRE(Java Runtime Environ…

FusionCharts Suite XT 3.20.X Crack

3.20版# 2023年3月24日 新功能 FusionCharts 3.20版本引入了一种新方法_changeXAxisCordinates,它允许用户自动更改x轴,使其在图例或数据交互时居中对齐。 FusionCharts 3.20版本更新了Angular集成,支持Angular版本14和15。 FusionChart…

HTML (Hyper Text Markup Language)

目录 网页(html文件) 什么是HTML? web标准 为啥需要web标准 web标准的构成 VScode的使用 HTML标签 基本语法 标签关系 结构标签 课间拓展: 了解骨架代码 HTML中常见的标签 标题标签 注释标签 段落标签 换行标签 文本格式化标签 div 和span 标签 图像标签 …

【vulnhub靶场】MATRIX-BREAKOUT: 2 MORPHEUS

文章目录 描述:一、开启靶机信息收集二层发现三层探测信息整理:初步攻击basic爆破:已知漏洞利用文件上传 后渗透测试后渗透测试 描述: 这是《黑客帝国》系列的第二部,副标题是《沉睡魔咒:1》。它的主题是回到第一部《…

chatgpt赋能python:Python如何在图片上添加文字

Python如何在图片上添加文字 对于网站的SEO优化而言,图片上的文字也是非常重要的一环。而Python是一种常用的编程语言,可以通过一些Python库来在图片上添加文字。 PIL库介绍 PIL(Python Imaging Library)是Python中常用的图像处…

面对日益增加的网络安全风险,需要全面的API安全

全球商业界在过去几年中面临的挑战是前所未有的。流行病、通货膨胀、能源危机、战争、经济衰退以及供应链的碎片化和延误都给组织带来了问题,没有一个行业、市场或地区未受影响。 然而,尽管存在这些问题,我们的数字生态系统和足迹变得越来…

chatgpt赋能python:Python如何更改主题

Python 如何更改主题 Python 是一种非常强大的编程语言,能够适用于多种领域,包括数据分析、机器学习、Web 开发等。Python 社区为开发者提供了各种主题,这篇文章将介绍 Python 如何更改主题。 什么是主题? 主题是指编程环境的外…