CMU_15445_P3_Part3

news/2025/1/11 16:12:33/文章来源:https://www.cnblogs.com/wevolf/p/18665804

HashJoin Executor & Optimization

如果查询包含与两列之间单个或者多个等值条件的连接的连接, 则 DBMS 可以使用 HashJoinPlanNode (各个等式之间使用 AND 连接条件), 例如: 考虑以下示例查询:

SELECT * FROM __mock_table_1, __mock_table_3 WHERE colA = colE;
SELECT * FROM __mock_table_1 INNER JOIN __mock_table_3 ON colA = colE;
SELECT * FROM __mock_table_1 LEFT OUTER JOIN __mock_table_3 ON colA = colE;
SELECT * FROM test_1 t1, test_2 t2 WHERE t1.colA = t2.colA AND t1.colB = t2.colC;
SELECT * FROM test_1 t1 INNER JOIN test_2 t2 on t1.colA = t2.colA AND t2.colC = t1.colB;
SELECT * FROM test_1 t1 LEFT OUTER JOIN test_2 t2 on t2.colA = t1.colA AND t2.colC = t1.colB;

我的理解是先对左边的 LeftTable 以及右边的 RightTable 进行 Hash 分组, 例如上面的语句

SELECT * FROM test_1 t1 INNER JOIN test_2 t2 on t1.colA = t2.colA AND t2.colC = t1.colB;

先对 Table t1 的 colA 与 colB 进行 GROUP BY 分组, 这个分组类似与 Aggregate GROUP BY 语句中的分组, 用于构建一个 HashTable 的 Keys, 对 Table t2 执行相同的操作, 执行完之后将两个 HashTable 进行按照条件组合即可获取 Join 之后的 tuples.

HashJoin 中 HashTable 的构建

这里 HashTable 的主要功能是将需要 JOIN 的两张表中的 tuples 按照 column 进行分组, 例如, 上面的例子

SELECT * FROM test_1 t1 INNER JOIN test_2 t2 on t1.colA = t2.colA AND t2.colC = t1.colB;

中, 对 t1 表就使用 colAcolB 进行分组, 而 t2 表就按照 colCcolA 进行分组. 分组的本质与 GROUP BY 语句相同, 只是在构建 HashTable 的时候不同.

在 HashJoin 中构建 HashTable 的时候, 我们可以参考 AggregationPlanNode 构建类似的 HashTable, 其中 HashTable 的 Key 和 Value 的定义如下:

/*** HashJoinKey represents a key in the hash table used in the hash join. it from the ON clause of the JOIN statement.*/
struct HashJoinKey {/** The group-by values */std::vector<Value> group_bys_{};/*** Compares two HashJoin keys for equality.* @param other the other HashJoin key to be compared with* @return `true` if both HashJoin keys have equivalent group-by expressions, `false` otherwise*/auto operator==(const HashJoinKey &other) const -> bool {for (uint32_t i = 0; i < other.group_bys_.size(); i++) {if (group_bys_[i].CompareEquals(other.group_bys_[i]) != CmpBool::CmpTrue) {return false;}}return true;}
};/** HashJoinValue represents a value for each of the running hashjoin */
struct HashJoinValue {/** The hashjoin tuples */std::vector<Tuple> tuples_{};
};

不同点是, HashJoinValue 是一个 tuples 数组, 在 SimpleAggregationHashTable 中, 由于 Aggregate 操作会将 GROUP BY 的结果进行计算, 因此 HashJoinValue 直接记录计算的结果即可. 而在 HashJoin 中, 后续需要将数组中的每个 tuple 与另一张 HashTable 中相同的 Key 对应的 tuples 进程组合, 得到一个组合的 tuple.
HashTable 的其他部分与 SimpleAggregationHashTable 类似.

HashJoinPlanNode 中, 有左表达式与右表达式的 Key 计算的 Expression, 也就是下面的

std::vector<AbstractExpressionRef> left_key_expressions_;

使用这个表达式可以计算出 Key, 但是 Key 不需要是特殊的结构体, vector<Value> 应该就可以了,

最大的问题应该是当存在多个 Value 对应同一个 Key 的时候

Optimizing NestedLoopJoin to HashJoin

在优化的时候按照提示, 有三点需要注意的, 分别是:

  1. 在原来的 NestedLoopJoinPlanNode 的表达式 predicate_ 中, 这个表达式中,

后续补充知识点

  1. 为什么在这个 Project 中只实现了 INNER JOIN 与 LEFT JOIN 呢, 这是涉及到查询优化以及遍历检索的时的 INNER TABLE 与 OUTER TABLE.
  2. 例如 select * from temp_3 t3 left join temp_2 t2 on t2.colA = t3.colB;
    select * from temp_3 t3 left join temp_2 t2 on t3.colB = t2.colA;

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

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

相关文章

JAVA-Day 12:方法的定义和调用

方法的定义和调用 方法定义的格式: public static void 方法名(){方法体(就是打包起来的代码)} 方法调用的格式: 方法名(); 定义调用一个方法用于个人介绍 public static void main(String[] args){myself(); } public static void myself(){System.out.println("小王同学…

PC电脑屏幕实时翻译工具-Translumo

点击上方蓝字关注我 前言 Translumo是基于.Net开发的、开源屏幕翻译器软件,它可以实时检测并翻译屏幕上所选区域中出现的文本,可检测视频中的字幕或图片中出现文字等 安装环境 [名称]:Translumo [大小]:500MB [版本]:0.9.6 [语言]:简体中文 [安装环境]:Windows 界面使用…

Text1-综合练习5

Text-综合练习5 产生十个1-100之间的随机数存入数组 求和 求平均数 找出有几个数字比平均值小 Random number1=new Random();Scanner number2=new Scanner(System.in);System.out.println("请输入要产生随机数的个数:");int n=number2.nextInt();int arr[]=new int […

Text1-综合练习6

Text-综合练习6 键盘录入n个数字,倒放他们的顺序 例如:输入1 2 3 4 5,输出5 4 3 2 1 Scanner EX=new Scanner(System.in);String arr[]=new String[100];String temp;int count=0;System.out.println("请输入要交换的数字:,以空格结束");for (int i = 0; i < 1…

Text1-综合练习2

Text-综合练习2 键盘录入一个大于2的整数,求它的平方根 结果省去小数部分保留整数 Scanner st=new Scanner(System.in);System.out.println("请输入一个大于2的整数:");int number1=st.nextInt();for(int i=1;i<number1;i++){//从1开始查找一直到number1的值int n…

Text1-综合练习1

Text1-综合练习1 逢七过 游戏规则:从任意一个数字开始报数 当你要报的数字包含七或者是七的倍数时都要说过 需求:使用程序在控制台打印出1-100之间满足逢七过规则的数 for(int i=1;i<=100;i++){if(i/10%10==7||i%10==7||i%7==0){//判断十位、个位有没有七,这个数是否能被七…

ciscn_2019_n_8 1

checksec一下能发现开了很多保护,吓人一跳,但其实我们分析一下发现只要var[13]为17就可以了if ( *(_QWORD *)&var[13] )#判断var[13]开始的8字节(_QWORD表示64位,即8字节)内存区域是否非零。*(_QWORD *)&var[13]是将var[13]的地址转换为_QWORD(64位整数)指针,然…

Unity URP Shader Graph 实现复古电视机效果

想到一出实现一出的复古电视机效果实现。复古电视机效果显示展示:使用素材 一张纹理需要放映的图片,一张遮罩贴图,一个电视机模型。UV使用Spherize模拟电视机球状显示屏。 扫描线A效果扫描线B效果像素化/随机UV偏移屏幕做旧效果边缘变暗效果屏幕黑边效果 自制一张合适的贴图…

终于决定:把自己家的能源管理系统开源了!

决定了很久把自己公司的能管平台开源了,部分功能和bug正在修复中。 欢迎star 欢迎轻拍 地址:https://gitee.com/ustcyc/zhitan-ems 介绍 通过物联网技术,采集企业水、电、气、热等能耗数据,帮企业建立能源管理体系,找到跑冒滴漏,从而为企业节能提供依据。 进一步为企业实…

Text-Switch的练习1

Text-Switch的练习1 键盘录入一个从一到七的数字表示星期 星期一到星期五是工作日 星期六和星期日是休息日 Scanner xq=new Scanner(System.in);System.out.println("请输入一个一到七之间的数字");int week=xq.nextInt();switch(week){case 1 :case 2 :case 3 :case…

Omnissa Dynamic Environment Manager 2412 - 个性化动态 Windows 桌面环境管理

Omnissa Dynamic Environment Manager 2412 - 个性化动态 Windows 桌面环境管理Omnissa Dynamic Environment Manager 2412 - 个性化动态 Windows 桌面环境管理 Simplify management of user profiles, environment settings, and policies across desktops and apps. 请访问原…

stata 检查哪些变量有缺失值

ssc install nmissing nmissing 说明这十个变量有缺失