当前位置: 首页 > news >正文

视图合并机制解析 | OceanBase查询优化

背景

在默认配置下,若查询语句中嵌入了视图,系统会先等待视图内部所包含的查询完全执行完成后,再继续执行父查询。这种方式造成优化器无法将视图查询与外层查询视为一个整体来进行优化处理,从而限制了优化效果。因此,Oceanbase数据库特别引入了视图合并机制,该机制能够将视图中的查询逻辑整合到父查询之中,从而进一步提升优化器的优化效果。

视图合并的基本原理

视图合并规则主要包含对以下两种情况的处理:

  1. from视图合并:将from子句中涉及的视图与父查询合并,消除视图查询。
  2. semi join视图合并:将semi join子句中涉及的视图与父查询合并,消除视图查询。

from视图合并

考虑如下情况:

SELECT t1.c1, v.c2, v.c3 FROM (SELECT t2.c2, t3.c3 FROM t2, t3 WHERE t2.c1 = t3.c1) v, t1, WHERE t1.c1 = v.c1

上述例子在默认情况下,只能严格按照视图的定义进行join操作,优化器无法对连接顺序进行优化。可以考虑将视图查询与父查询合并,如下所示:

SELECT t1.c1, t2.c2, t3.c3 FROM t1, t2, t3 WHERE t1.c1 = t2.c1 AND t1.c1 = t3.c1

semi join 视图合并

考虑如下情况:

SELECT t1.c1 FROM t1 LEFT SEMI JOIN (SELECT c1 FROM t2) v WHERE t1.c1 = v.c1

上述情况下中的视图为简单查询,本身没有实际意义,可以考虑通过合并消除视图,如下所示:

SELECT t1.c1 FROM t1 LEFT SEMI JOIN t2 WHERE t1.c1 = t2.c1

代码解析

视图合并规则的入口为ObTransformViewMerge::transform_one_stmt,该函数的主要执行流程如下:

  1. 调用transform_in_from_item函数执行from视图合并。
  2. 调用transform_in_semi_info函数执行semi join视图合并。

from视图合并

transform_in_from_item会遍历父查询在from子句中使用的表,然后根据表的类型分别执行合并操作,如下所示:

  1. 调用transform_joined_table函数对通过join操作连接起来的多个表形成的逻辑表执行视图合并。
  2. 调用transform_generated_table函数对视图表执行视图合并。

transform_joined_table函数会递归遍历join树直到叶子节点的基表或视图,然后调用transform_generated_table函数(与上面提到的函数为重载函数)执行视图合并。

在join树的视图合并的过程中涉及到一个问题,即视图中的where条件要放置在父查询的where还是join条件中,可以分为以下几种情况:

  1. 视图及所有父节点始终位于join树中外连接的外表一侧(left join的左侧或者right join的右侧),此时应该将where条件提取到父查询中。
  2. 视图及所有父节点始终位于join树中外连接的内表一侧(left join的右侧或者right join的左侧),此时应该将where条件提取到join条件中。
  3. 视图的某个父节点位于外连接的内表一侧,而视图位于外连接的外表一侧,此时如果视图中包含where条件,则无法完成改写。

下面对上述几种情况分别举例说明:

情况1,考虑如下查询:

SELECT * FROM t1 RIGHT JOIN (t2 RIGHT JOIN (SELECT * FROM t3 WHERE c2 <> 0) v ON t2.c1 = v.c1)ON t1.c1 = t2.c1

根据join的语义,可以将上述查询进行如下改写:

SELECT * FROM t1 RIGHT JOIN (t2 RIGHT JOIN t3 ON t2.c1 = v.c1)ON t1.c1 = t2.c1 WHERE t3.c2 <> 0

情况2,考虑如下查询:

SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN (SELECT * FROM t3 WHERE c2 <> 0) v ON t2.c1 = v.c1)ON t1.c1 = t2.c1

根据join的语义,可以将上述查询进行如下改写:

SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.c1 = t3.c1 AND t3.c2 <> 0)ON t1.c1 = t2.c1

情况3,考虑如下查询:

SELECT * FROM t1 LEFT JOIN (t2 RIGHT JOIN (SELECT * FROM t3 WHERE c2 <> 0) v ON t2.c1 = v.c1)ON t1.c1 = t2.c1

根据join的语义,如果按照情况1将where条件提取到父查询中,则该条件成为空值拒绝条件,父查询会被转换为内连接,与原始查询语义不符;如果按照情况2将where条件提取到join条件中,按照外连接的语义,也与原始查询语义不符。因此对于这种情况,无法完成改写。

同理,如果视图位于full join中且包含where条件,同样无法完成改写,这里不再进一步举例。

transform_generated_table函数有两个版本,分别负责对单视图执行合并以及对join树中的视图进行合并。该函数会调用check_can_be_unnested函数视图判断是否可以被合并,如果可以,则调用do_view_merge_transformation函数执行合并。

对于参与外连接的视图,如果视图位于left join的右侧或者right join的左侧以及full join的任意一侧,且视图中存在不满足空值传递的select表达式,则不能将select表达式直接合并到父查询中。

考虑如下情况:

SELECT * FROM t1 LEFT JOIN (SELECT 1, * FROM t2) vON t1.c1 = t2.c1

对于视图中的常量表达式,当t2中的列为null,其结果不会受到影响也变为null,因此如果将其直接合并到父查询,则与外连接的语义不符。为此我们可以选择一个t2中的非空列c2,然后进行如下改写:

SELECT t1.*, case t2.c2 when IS NOT NULL then 1 else NULL, t2.*FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1

check_can_be_unnested函数负责判断视图是否可以被合并。如果视图属于上述例子的情况,该函数会按照如下顺序找到一个非空列:

  1. 如果join条件中存在视图结果的某一列的空值拒绝条件,意味着在连接之前视图表中该列的空值均已被过滤,因此选择该列作为非空列。
  2. 如果视图查询的列中存在满足非空约束的列,则选择该列作为非空列。
  3. 如果上述条件都不满足,则选择视图查询表的主键作为非空列。

do_view_merge_transformation函数负责将视图与父查询合并,该函数的逻辑比较简单,主要是将视图查询涉及的信息更新到父查询中,这里不再赘述。

semi join视图合并

transform_in_semi_info函数负责将semi join子句中的视图与父查询进行合并,该函数会遍历父查询的semi join信息,然后调用check_semi_right_table_can_be_merged函数判断视图是否可以被合并。如果可以,则调用do_view_merge_for_semi_right_table函数执行合并。

do_view_merge_for_semi_right_table函数负责将semi join涉及的视图合并到父查询,该函数的逻辑比较简单,主要是将视图查询涉及的信息更新到父查询中,这里不再赘述。


相关文章:

视图合并机制解析 | OceanBase查询优化

背景 在默认配置下&#xff0c;若查询语句中嵌入了视图&#xff0c;系统会先等待视图内部所包含的查询完全执行完成后&#xff0c;再继续执行父查询。这种方式造成优化器无法将视图查询与外层查询视为一个整体来进行优化处理&#xff0c;从而限制了优化效果。因此&#xff0c;…...

sql注入报错分享(mssql+mysql)

mysql mysql的报错内容比较多 网上也有比较多的 这里重复的就不多介绍了。一笔带过 溢出类 bigint 当超过mysql的整形的时候&#xff0c;就会导致溢出&#xff0c;mysql可能会将错误信息带出。这里user()是字母默认为0 取反以后1可能就会导致异常。 报错特征 BIGINT UNSIG…...

PHP 高并发解决方案

PHP作为一种脚本语言&#xff0c;在处理高并发请求时可能面临一些挑战。但通过合理的设计和优化&#xff0c;可以有效提升PHP应用程序的性能和并发处理的能力。 一、缓存 页面缓存&#xff1a;将生成的页面缓存起来&#xff0c;减少对数据库的查询&#xff0c;提高响应速度。…...

k8s1.30.0高可用集群部署

负载均衡 nginx负载均衡 两台nginx负载均衡 vim /etc/nginx/nginx.conf stream {upstream kube-apiserver {server 192.168.0.11:6443 max_fails3 fail_timeout30s;#server 192.168.0.12:6443 max_fails3 fail_timeout30s;#server 192.168.0.13:6443 max_fails3…...

多摩川编码器协议及单片机使用

参考&#xff1a; https://blog.csdn.net/qq_28149763/article/details/132718177 https://mp.weixin.qq.com/s/H4XoR1LZSMH6AxsjZuOw6g 1、多摩川编码器协议 多摩川数据通讯是基于485 硬件接口标准NRZ 协议&#xff0c;通讯波特率为2.5Mbps 的串行通讯&#xff0c;采用差分两…...

Android 网络通信(三)OkHttp实现登入

学习笔记 目录 一. 先写XML布局 二、创建 LoginResponse 类 :封装响应数据 目的和作用: 三、创建 MyOkHttp 类 :发送异步请求 代码分析 可能改进的地方 总结 四、LoginActivity 类中实现登录功能 详细分析与注释: 总结: 改进建议: 零、响应数据样例 通过 P…...

分享一下arr的意义(c基础)(必看)(牢记)

arr 即数组名 一般指数组首元素地址 在两种情况下不是 1&#xff1a;sizeof&#xff08;arr&#xff09; arr指整个数组简单讲解一下strlen与sizeof&#xff08;c基础&#xff09;_strzeof在c语言中什么意思-CSDN博客 2&#xff1a;printf&#xff08;"%p",&…...

AGENT AI 综述核心速览

研究背景 研究问题&#xff1a;这篇文章探讨了多模态人工智能&#xff08;Agent AI&#xff09;系统在理解和响应视觉和语言输入方面的潜力&#xff0c;特别是在物理和虚拟环境中的应用。Agent AI旨在通过感知和行动来增强人工智能系统的交互性和适应性。研究难点&#xff1a;…...

基于Java Springboot房屋租赁系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…...

力扣 LeetCode 701. 二叉搜索树中的插入操作(Day10:二叉树)

解题思路&#xff1a; 全部插入到叶子节点即可 class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {if (root null) {TreeNode node new TreeNode(val);return node;}if (root.val < val) {root.right insertIntoBST(root.right, val);}if (root…...

猎板科技:PCB 特殊定制领域的卓越引领者

一、专业团队&#xff0c;创新设计之源 猎板科技的核心竞争力首先源于其卓越的专业团队。这支队伍汇聚了经验丰富的资深工程师以及行业前沿的技术专家&#xff0c;他们在 PCB 设计领域拥有深厚的造诣和敏锐的洞察力。无论是面对常规 PCB 设计任务&#xff0c;还是应对极具挑战…...

centos stream 9安装docker教程

第一步&#xff1a;安装该dnf-plugins-core软件包&#xff08;它提供了管理 DNF 存储库的命令&#xff09; sudo dnf -y install dnf-plugins-core 第二步&#xff1a;设置存储库(这里使用的是阿里云的镜像源) sudo dnf config-manager --add-repo https://mirrors.aliyun.c…...

优化旧LabVIEW程序功能的方法

优化运行已久的LabVIEW程序时&#xff0c;需在不影响原有功能的基础上针对目标功能进行改进。以下结合一个数据采集功能优化的实例&#xff0c;详细说明操作步骤和注意事项&#xff0c;为工程师提供切实可行的方法。 优化背景 某企业的LabVIEW程序负责多通道数据采集&#xf…...

关于安卓模拟器或手机设置了BurpSuite代理和安装证书后仍然抓取不到APP数据包的解决办法

免责申明 本文仅是用于学习研究安卓系统设置代理后抓取不到App数据包实验,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》【学法时习之丨网络安全在身边一…...

【电路笔记】-布尔逻辑AND函数

逻辑AND函数 文章目录 逻辑AND函数1、概述2、逻辑 AND 函数 仅当所有输入均为 true 时&#xff0c;逻辑与函数输出才为 true&#xff0c;否则输出为 false。 1、概述 布尔代数基于逻辑函数&#xff0c;其中每个布尔函数&#xff08;例如逻辑 AND 函数&#xff09;通常具有一个…...

C#(11) 运算符重载

前言 我们知道函数是可以重载的&#xff0c;重载后的作用是干嘛呢&#xff1f;其实就是为了方便适应不同的参数传递。 那运算符我们也可以理解是一个函数&#xff0c;只是我们希望为更多的参数引入运算符使得他们可以被计算。 c#设计这么一块功能&#xff0c;其实也是为了方…...

Linux下Intel编译器oneAPI安装和链接MKL库编译

参考: https://blog.csdn.net/qq_44263574/article/details/123582481 官网下载: https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit-download.html?packagesoneapi-toolkit&oneapi-toolkit-oslinux&oneapi-linoffline 填写邮件和国家,…...

【通俗理解】ELBO(证据下界)——机器学习中的“情感纽带”

【通俗理解】ELBO&#xff08;证据下界&#xff09;——机器学习中的“情感纽带” 关键词提炼 #ELBO #证据下界 #变分推断 #机器学习 #潜变量模型 #KL散度 #期望 #对数似然 第一节&#xff1a;ELBO的类比与核心概念【尽可能通俗】 ELBO&#xff0c;即证据下界&#xff0c;在…...

php 使用mqtt

在 Webman 框架中使用 MQTT 进行消息的发布和订阅&#xff0c;你可以借助 PHP 的 MQTT 客户端库&#xff0c;比如 phpMQTT。以下是一个简单的示例&#xff0c;展示了如何在 Webman 中使用 MQTT 发布和订阅消息。 安装 phpMQTT 首先&#xff0c;你需要通过 Composer 安装 phpMQ…...

STM32学习笔记-----什么是同步/异步/全双工/半双工/单工?

在通信系统中&#xff0c;同步、异步、全双工、半双工和单工是描述数据传输方式的重要概念。在STM32微控制器中&#xff0c;这些概念广泛应用于串行通信&#xff08;如USART、SPI和I2C协议&#xff09;中。接下来&#xff0c;我会详细解释这些术语&#xff0c;并特别关注STM32中…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...