Parallel Join Algorithms (Hashing)
背景
我们在执行Join操作的时候,肯定会使用多线程。但是这些多线程不是完全独立运行的,因为你需要在进入下一个阶段前将这一个阶段的所有数据处理完,而不能让一个线程先进入下一个阶段。所以如何设计Join算法来减少overhead就是非常关键的事情了。
这篇文章我们将介绍Hash Join的算法,下片文章介绍的是Sort-Merge Join算法。
关于Sort Merge Join和Hashing Join的争论持续了非常长的时间。
实际上,很多数据库并没有实现Hash Join。因为在小数据的Join操作上,Index nested-loop Join和Hash Join差不太多。
Join算法的设计目标
目标1:最小化同步
- 在执行过程中避免使用锁存器。
目标2:最大限度地减少CPU高速缓存未命中
- 确保工作线程的数据始终是本地的。
改善高速缓存行为
影响DBMS中缓存未命中的因素:
- 缓存+ TLB容量
- TLB是translation and localiztion buffer,用于将虚拟地址映射到物理地址,可能会因为太过频繁的交换而堵塞
- 如果访问了别的服务器,那么本机的TLB和服务器的TLB都需要存储数据位置的信息,占用了双重的空间。
- 地点(时间和空间)。
非随机访问(扫描):
- 群集到缓存线。
- 每个缓存行执行更多的操作。
随机访问(查找):
- 分区数据,以适应缓存+ TLB。
并行Hash JOIN
Hash Join是DBMS中用于OLAP工作负载的最重要的操作。在多线程的情况下,如何充分利用每一个core是算法设计的目标。
CLOUDERA IMPALA
大家看这个饼图,就可以发现Hash Join占用了最大的时间,也就说,如果能够优化Hash Join,则对整个系统的提升是最大的。
HASH JOIN
Hash Join分为三个阶段。
阶段1:分区(可选)
- 使用连接键上的散列将R和S的元组划分为集合。
- 有可能在某些情况下使用分区会导致更慢的结果,所以需要用优化器(optimizer)去决定是否使用。
阶段2:构建
- 扫描关系R并在连接键上创建一个散列表。
阶段#3&#