一. 前言
Cross Join是指无条件的join。因为Cross Join的代价为笛卡尔乘积,代价很大,因此在Presto的执行优化中,会尽量消除掉Cross Join。Presto Cross Join的消除原理主要是尽可能通过对Join表的重新排序实现将Cross Join转换为Inner Join。本文主要讲述在Presto中是如何实现Cross Join消除的。
二. Cross Join消除的样例。
以“SELECT * FROM part p, orders o, lineitem l WHERE p.partkey = l.partkey AND l.orderkey = o.orderkey” 为例,在cross join消除前执行计划如下所示:
因为lineitem与order表之间无关联条件,因此产生了Cross Join。
通过调整表的顺序后,可以将cross join转换成inner join,消除后的执行计划如下所示:
三. Cross Join消除的实现
在Presto中,消除Cross Join的实现是在EliminateCrossJoins的RBO规则中实现的。其实现代码主要分成如下两步:
-
首先根据Join条件构建出各个Join表的图结构(JoinGraph),如下图中所示的表是上述SQL构造出的图:
2. 使用BFS算法遍历图中的各个表,如果表与表之间能有路径达到,则说明两表之间可以产生On的过滤条件,Join可以转换成Inner Join。如上述的图结构:
首先遍历part,part可以和lineitem产生inner join,然后结果又可以和order 产生inner join,因此上述的图可以产生两个inner join来消除part与order之间的cross join。
BFS返回的是表的Join顺序。
3. 根据2中返回的表的Join顺序重新生成Join的执行计划。