外连接转AntiJoin的应用场景与限制条件 | OceanBase SQL 查询改写系列

在《SQL 改写系列:外连接转内连接的常见场景与错误》一文中,我们了解到谓词条件可以过滤掉连接结果中的 null 情形的,将外连接转化为内连接的做法是可行的,正如图1中路径(a)所示。此时,敏锐的你或许会进一步思考:当谓词成功筛选出这些因连接补的NULL行后,是否还隐藏着其他的优化空间?

答案可以参考图1中路径(b)所示:对于左外连接(LeftJoin)或右外连接(RightJoin),OceanBase会把外连接转位AntiJoin。在LeftJoin和RIghtJoin场景,驱动表(在这个例子中是t1)需要扫描被驱动表(t2)的所有行,找出所有匹配的行。 但转换成AntiJoin之后,由于AntiJoin的目的是输出没有在被驱动表中找到匹配行的驱动表中的行,因此在AntiJoin场景,只要在被驱动表中找到一行满足连接条件的数据,我们就可以认为驱动表中的行不满足输出条件,就可以停止这轮扫描。综上,我们可以知道LeftJoin/RightJoin转换成AntiJoin之后可以减少扫描被驱动表的行数

更多内容可以查看【OceanBase 查询改写】系列


 

外连接转AntiJoin

对于左外连接和右外连接,当针对基表的过滤谓词可以筛选出因为连接而补null的行时,我们可以把外连接转化为AntiJoin。图2以最简单的过滤谓词 column is null为例描述了不同外连转AntiJoin的场景。

然而在实际查询中,谓词不会一直像 t2.c1 is null 这么简单。在一个 SQL 语句中,is null 谓词的左边可以是复杂表达式{如(t2.c1 + t2.c2) is null},于是,我们进一步推广支持外连接转AntiJoin的谓词形态,让这个改写在复杂谓词条件下也能发生,并且结合前文提到的谓词推导和谓词移动,使更多的查询能从外连接转AntiJoin中获益。在了解复杂条件的改写之前,我们需要先了解OceanBase中空值传递的概念。

对于复杂表达式 A = b+c+d,它是由表达式 b,c,d构成的。假设当b为null的时候,表达式A也会null,那我们则认为表达式A对于表达式b是空值传递的。 在这个例子中,表达式A对于b, c, d都是空值传递的。常见的空值传递判断条件有:

  1. 表达式对自身是空值传递的
  2. 基本的算数表达式对其子表达式都是空值传递的
  3. 一些系统函数(SQRT,LOG_TEN,LOG_TWO,FLOOR,CEIL,LEAST,GREATEST,LEAST_INNER,GREATEST_INNER,MIN,MAX,SUM等)
  4. 非AND/OR/IS/IS NOT的布尔表达式

在了解空值传递这个概念后,我们可以知道:只要is null谓词左边的表达式对于被驱动表中的列是空值传递的(如 (t2.c1+t2.c2) 对于t2.c1是空值传递的),那在t2.c1是null的时候is null谓词左边的表达式也是null,is null谓词结果为true,如此便可以把被驱动表补null的行筛选出来。

综上所述,我们知道即便是对于 (t2.c1+t2.c2) is null这样的复杂谓词,只要满足对被驱动表中的列空值传递的条件,在特定条件也可以做外连接转AntiJoin的改写。至于这个特定条件是什么,我们接着往下看。

改写限制条件

条件1:对于补null侧的基表,谓词中的列不能存在null值。

-- 影片表
MOVIE(movie_id, movie_name)
movie_id	movie_name
1					'Gone With Wind'
2					'Leon'
-- 排片表
PLAY(play_id, movie_id, time, price)
play_id	movie_id	time					price
1				1					'2022-10-01'	35
2				1					NULL					40Q1: 
SELECT 	MOVIE.movie_name,PLAY.time
FROM	 	MOVIELEFT JOIN PLAYON	MOVIE.movie_id = PLAY.movie_id;
WHERE		PLAY.time is null;-- 外连接结果
R1:
movie_name				price
'Gone With Wind'	40
'Leon'						NULL-- AntiJoin结果
R2:
movie_name				time
'Leon'						NULL

条件2:对于非补null侧的基表, 谓词中的列不应该对谓词是空值传递的。

-- 影片表
MOVIE(movie_id, movie_name)
movie_id	movie_name
1					'Gone With Wind'
2					NULL
-- 排片表
PLAY(play_id, movie_id, time, price)
play_id	movie_id	time					price
1				1					'2022-10-01'	35
2				2					'2022-10-02'	40Q2: 
SELECT 	MOVIE.movie_name,PLAY.time
FROM	 	MOVIELEFT JOIN PLAYON	MOVIE.movie_id = PLAY.movie_id;
WHERE		(PLAY.time AND MOVIE.movie_name) is null;-- 外连接结果
R3:
movie_name				price
NULL							40-- AntiJoin结果
R4:
movie_name				time	

总结

看到这里,相信你已经了解了LeftJoin和RightJoin改写为AntiJoin的优点及适用场景,相较于LeftJoin和RightJoin需要扫描被驱动表的所有行,AntiJoin在找到第一行匹配的数据后就会停止扫描被驱动表,可以减少实际扫描数据的数量,因而在执行的时候有更好的性能。我们认为,谓词能筛选出被驱动表补null的行时,就能进行半连接转Anti的改写,但是依旧需要注意数据原本就可能为null的情况。此外,借助空值传递的概念,我们把能做改写的场景从简单谓词场景推广到了复杂谓词场景。

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

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

相关文章

二、windows环境下vscode使用wsl教程

本篇文件介绍了在windows系统使用vscode如何连接使用wsl,方便wsl在vscode进行开发。 1、插件安装 双击桌面vscode,按快捷键CtrlShiftX打开插件市场,搜索【WSL】点击安装即可。 2、开启WSL的linux子系统 点击左下方图标【Open a Remote Win…

【嵌入式linux基础】GDB调试技巧

使用GDB(GNU调试器)对嵌入式Linux应用程序进行调试是开发过程中非常重要的技能。以下是几个实用的GDB调试技巧,可以帮助你更高效地调试嵌入式系统上的程序: 1. 远程调试设置 由于嵌入式设备资源有限,通常不会直接在目…

shell脚本中 cp 命令直接覆盖不提示

cp 命令直接覆盖不提示 原因:执行cp命令默认执行了cp -i命令的别名,-i作用是提示是否覆盖,这就是总是提示的原因 alias cpcp -ishell脚本中需要直接覆盖不提示 解决方案: 方案1: cp命令前加个右斜杠即可&#xff0…

因子问题(真EASY)

描述 任给两个正整数N、M,求一个最小的正整数a,使得a和(M-a)都是N的因子。 输入描述 包括两个整数N、M。N不超过1,000,000。 输出描述 输出一个整数a,表示结果。如果某个案例中满足条件的正整数不存在,则在对应行输出-1 用例…

2024 高频 Java 面试合集整理 (1000 道附答案解析)

2024 年马上就快要过去了,总结了上半年各类 Java 面试题,初中级和中高级都有,包括 Java 基础,JVM 知识面试题库,开源框架面试题库,操作系统面试题库,多线程面试题库,Tcp 面试题库&am…

(2024.12)Ubuntu20.04安装openMVS<成功>.colmap<成功>和openMVG<失败>记录

一、安装openMVS 官方文档:https://github.com/cdcseacave/openMVS/wiki/Building sudo apt-get -y install git mercurial cmake libpng-dev libjpeg-dev libtiff-dev libglu1-mesa-dev eigen git clone https://gitlab.com/libeigen/eigen --branch 3.4 mkdi…

怎么实现柔性动态自适应IVR功能

怎么实现柔性动态自适应IVR功能 作者:开源大模型智能呼叫中心系统FreeAICC,Github:https://github.com/FreeIPCC/FreeAICC 实现柔性动态自适应IVR(Interactive Voice Response,交互式语音应答)功能是一个…

minikube start --driver=docker --force

minikube start --driver=docker --force 😄 minikube v1.34.0 on Debian 11.7 (amd64) ❗ minikube skips various validations when --force is supplied; this may lead to unexpected behavior ✨ Using the docker driver based on user configuration 🛑 The…

Springboot+Druid(可切换Hikari)+Mybatis-plus+mysql+hive的多数据源项目配置

1.搭建一个springboot项目&#xff0c;不会的搜一下&#xff0c;很简单这里不做赘述。 2.首先你搭建的springboot能正常启动之后&#xff0c;pom文件添加如下依赖&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>druid</arti…

自动控制系统综合与LabVIEW实现

自动控制系统综合是为了优化系统性能&#xff0c;确保其可靠性、稳定性和灵活性。常用方法包括动态性能优化、稳态误差分析、鲁棒性设计等。结合LabVIEW&#xff0c;可以通过图形化编程、高效数据采集与处理来实现系统综合。本文将阐述具体方法&#xff0c;并结合硬件选型提供实…

服务器上加入SFTP------(小白篇 1)

在服务器上配置 SFTP (基于 SSH 的文件传输协议) 通常比传统 FTP 更安全&#xff0c;因为它默认加密通信。以下是详细的配置步骤&#xff0c;以 Ubuntu 或 CentOS 为例。 1.服务器上加入SFTP------(小白篇 1) 2.加入SFTP 用户------(小白篇 2) 3.代码加入SFTP JAVA —&#…

高级java每日一道面试题-2024年12月23日-并发篇-CAS有什么缺点吗 ?

如果有遗漏,评论区告诉我进行补充 面试官: CAS有什么缺点吗 ? 我回答: CAS&#xff08;Compare-And-Swap&#xff0c;比较并交换&#xff09;是一种无锁算法的核心操作&#xff0c;广泛用于实现并发控制。它通过硬件指令直接在内存中进行原子操作&#xff0c;避免了传统锁机…

【恶意软件检测】一种基于API语义提取的Android恶意软件检测方法(期刊等级:CCF-B、Q2)

一种基于API语义提取的Android恶意软件检测方法 A novel Android malware detection method with API semantics extraction 摘要 由于Android框架和恶意软件的持续演变&#xff0c;使用过时应用程序训练的传统恶意软件检测方法在有效识别复杂演化的恶意软件方面已显不足。为…

FLTK - build fltk-1.1.10 on vs2019

文章目录 FLTK - build fltk-1.1.10 on vs2019概述笔记buildtest测试程序运行 END FLTK - build fltk-1.1.10 on vs2019 概述 看书上用到了fltk-1.1.10, 用vs2019试试能否正常编译使用? 笔记 build 从官网下载fltk-1.1.10-source.tar.bz2 用7zip解开 fltk-1.1.10-source.…

业财融合,决策有据:工程项目管理的财务新视角

在工程项目管理领域&#xff0c;业财融合正开启全新篇章。传统模式下&#xff0c;业务与财务各自为政&#xff0c;常导致信息滞后、决策盲目。如今&#xff0c;借助先进理念与技术&#xff0c;二者紧密相连。 在项目规划阶段&#xff0c;财务部门依据业务需求与市场趋势&#…

亚远景-SO 21434标准下的汽车网络安全:风险评估与管理的关键实践

ISO 21434标准&#xff0c;全称为ISO/SAE 21434 "Road Vehicles - Cybersecurity Engineering"&#xff0c;是国际标准化组织(ISO)发布的针对汽车领域的标准&#xff0c;旨在指导汽车制造商、供应商和相关利益相关方在汽车系统中应用适当的网络安全措施。在ISO 21434…

汽车IVI中控开发入门及进阶(44):杰发科智能座舱芯片

概述: 杰发科技自成立以来,一直专注于汽车电子芯片及相关系统的研发与设计。 产品布局: 合作伙伴: 杰发科技不断提升产品设计能力和产品工艺,确保产品达 到更高的质量标准。目前杰发科技已通过ISO9001质 量管理体系与CMMIL3认证。 杰发科技长期合作的供应商(芯片代工厂、…

MFC/C++学习系列之简单记录——序列化机制

MFC/C学习系列之简单记录——序列化机制 前言简述六大机制序列化机制使用反序列化总结 前言 MFC有六大机制&#xff0c;分别是程序启动机制、窗口创建机制、动态创建机制、运行时类信息机制、消息映射机制、序列化机制。 简述六大机制 程序启动机制&#xff1a;全局的应用程序…

算法专题——双指针

目录 前言 1、移动0 2、复写零 3、快乐数 4、盛最多水的容器 5、有效三⻆形的个数 6、和为s的两个数字 7、三数之和 8、四数之和 前言 本文主要介绍一些用到双指针的常见算法题。 1、移动0 链接&#xff1a;https://leetcode.cn/problems/move-zeroes/description/…

Spark任务的执⾏流程

Spark 任务的执行流程涉及多个组件和步骤的协同工作&#xff0c;以下是其详细的执行流程&#xff1a; 提交任务 编写应用程序&#xff1a;用户首先使用 Spark 支持的编程语言&#xff08;如 Scala、Java、Python 等&#xff09;编写 Spark 应用程序&#xff0c;在应用程序中定…