洗牌连接
SmartESQL 在执行表连接操作时实现了经典的“洗牌连接”映射归约算法。例如,考虑需要通过如下语句进行连接的两个表:
select * from A join B on A.id = B.id;
首先,外部表 A 通过 A.id 的哈希值进行散列操作,例如 hash(A.id) mod nChunks,将其分散成几个块。如果 nChunks 为 3,则会生成三个块 A1、A2 和 A3。然后,内部表 B 以同样的方式分散,生成文件 B1、B2 和 B3。
现在可以使用(A1,B1)、(A2,B2)和(A3,B3)这些配对来执行连接操作。
此方法允许连接两个无法全部装入内存的表。nChunks 的值被选定为使得文件 Bi 中的数据能够装入内存。每个数据块都存储在各自的文件中。然后,通过表 A 和表 B 各使用一条路径将数据追加到相应的文件中,这不会消耗内存。接着遍历“数据块文件”对,将内部数据块装入内存中的哈希表,并通过内存中的哈希查找扫描内部数据块。
分布式洗牌连接
分布式洗牌连接基于同样的理念,但在这种情况下数据分散在多个节点之间。每个节点仅存储一对数据块(Ai,Bi)。(请注意,假定数据在节点之间的分区方式使得每个分区都能在内存中容纳。)
与本地洗牌连接不同,分布式洗牌连接节点必须交换数据。因此,需要在集群中的每个节点之间建立连接。(这仅对分布式洗牌连接是必需的,所有其他分布式查询仅需要协调器和工作节点之间的通信)。