10.2.3 多表操作

多表相关的物理操作符主要是Join。最为常见的Join类型包括两种:内连接(Inner Join)和左外连接(Left Outer Join),而且基本都是等值连接。如果需要连接多张表,可以先连接前两张表,再将前两张表连接生成的结果(相当于一张临时表)与第三张表格连接,以此类推。

两张表实现等值连接方式主要分为两类:基于排序的算法(MergeJoin)以及基于哈希的算法(HashJoin)。对于MergeJoin,首先使用Sort运算符分别对输入表格预处理,使得两张输入表都在连接列上排好序,接着按顺序迭代两张输入表,合并连接列相同的行并输出;对于HashJoin,首先根据连接列计算哈希值K,并分别将两张输入表格的数据写入到第K个桶中。接着,对每个哈希桶按照连接列排序。最后,依次对每个哈希桶合并连接列相同的行并输出。

子查询分为两种:关联子查询和非关联子查询,其中比较常用的是使用IN子句的非关联子查询。举例如下:

例10-3 假设有两张表格:item(商品表,包括商品号item_id,商品名item_name,分类号category_id,),category(类别表,包括分类号category_id,分类名category_name)。如果需要查询分类号出现在category表中商品,可以采用图10-4左边的IN子查询,而这个子查询将被自动转化为图10-4右边的等值连接。如果category表中的category_id列有重复,表连接之前还需要使用distinct运算符来删除重复的记录。

10.2.3 多表操作 - 图1

图 10-4 IN子查询转化为等值连接

例10-4 例10-3中,如果category表只包含category_id为1~10的记录,那么,可以将IN子查询写成图10-5中的常量表达式。

10.2.3 多表操作 - 图2

图 10-5 IN子查询转化为常量表达式

转化为常量表达式后,MergeServer执行SQL计算时,可以将IN后面的常量列表发送给ChunkServer,ChunkServer只返回category_id在常量列表中的商品记录,而不是将所有的记录返回给MergeServer过滤,从而减少二者之间传输的数据量。

OceanBase多表操作做得还很粗糙,例如不支持嵌套连接(Nested Loop Join),不支持非等值连接,不支持查询优化等,后续将在合适的时间对这一部分代码进行重构。