1. 为什么我们需要 Join
我们对关系数据库中的表【tables】进行规范化【normalize】,这样我们就减少了信息的冗余和浪费的空间,但是现在我们为了可以响应传入的查询【Query】,我们必须把这些分离的东西重新组合在一起,以重建原始元组,而不会丢失任何信息,这就是 Join 要做的。
2 Join 算法
我们本节将重点关注使用内等联接算法【inner equijoin algorithms】执行二元连接(两个表)。
- 可以调整这些算法以支持其他连接。
- 多路【Multi-Way】连接主要存在于研究文献中。
一般来说,我们希望较小的表始终是查询计划【QueryPlan】中的左表【Left Tabe】(左指的是它位于 Join 操作符的左边)(“外部表【outer table】”)。
- 优化器在生成物理计划【physical plan】时将(尝试)解决这个问题。
3. Join 操作符

在前面讲排序算法时,我们认识了查询计划。并且也看到了 SQL 被转换为查询计划的操作符树。
在 Join 的操作符实现中,我们有两个方面需要考虑:
考虑点 1:输出【Output】:连接运算符【Join Operator】向查询计划树中的父操作符发送哪些数据?
考虑点 2:成本分析标准:我们如何确定两种算法中,那种连接算法最优?
3.1 操作符输出
对于在连接属性【join attributes】上匹配的元组 r ∈ R 和元组 s ∈ S,将 r& s 连接在一起形成一个新元组。

输出内容可能有所不同:
- 取决于处理模型【processing model】,比如如果是排序-归并 Join【Sort Merge Join】 ,那么数据是有序的,但是如果是哈希 Join,那么数据就是无序的
- 取决于存储模型【storage model】,比如行存储还是列存储,数据的组织是不同的
- 取决于查询【Query】对数据的要求,比如是全部字段返回,还是只返回特定几个字段
3.1.1 操作符输出:DATA(直接输出数据)
提前物化【Early Materialization】:将外部元组和内部元组中的属性值复制到新的输出元组中。
- 缺点:在表非常宽的时候,我们将有非常多的属性,我们拷贝了很多用不到的属性
- 优点:查询计划中的后续操作符永远不需要返回基表来获取更多数据,因为连接操作符返回的数据就是完整的。

3.1.2 操作符输出:Record ID
延迟物化【Late Materialization】:仅复制连接键【Join Keys】以及匹配元组的Record ID。
- 优点:非常适合列存储,因为 DBMS 不会复制查询不需要的数据。
- 缺点:后面进行映射操作时,可能需要回基表

3.2 成本分析标准【Cost Analysis Criteria】
假定:
- 表 R 占据 M 个页面,R 表中有 m 个元组
- 表 S 占据 N 个页面,S 表中有 n 个元组
成本指标:用于计算连接【Join】所使用的 IO 数量。
我们将忽略计算机计算的成本,我们也忽略操作符的输出成本【output cost】,因为这取决于数据,而我们尚无法计算。
3.2.1 Join VS Cross Product
我们这里区分一下 Join 和 笛卡尔积的区别:
- R⨝S 是最常见的运算,因此必须仔细优化。
- R×S 后进行选择【selection】的效率很低,因为笛卡尔积很大。
有很多降低连接成本的算法,但没有一种算法可以在所有场景下都有效。
注:很少有系统回采用笛卡尔积,因为它太慢了,除非是查询指定进行笛卡尔积操作。
3.2.2 Join 算法
嵌套循环连接【Nested Loop Join】
- Simple / Stupid
- Block
- Index
排序合并连接【Sort Merge Join】
哈希连接 【Hash Join】
3.2.2.1 嵌套循环连接【Nested Loop Join】
Naïve嵌套循环连接
我们首先认识左表/外表和右表/内表,我们要做

本文详细解释了数据库中Join的概念,包括规范化带来的好处和Join的需求,重点介绍了内连接算法(如嵌套循环、排序-归并和哈希Join),讨论了各种连接操作的成本分析、输出策略和优化技术,以及在不同场景下的适用性。
最低0.47元/天 解锁文章
1168

被折叠的 条评论
为什么被折叠?



