目录:
1.左表 join 后条件下推
2.左表join中条件不下推
3.右表join中条件下推
4.右表join中条件不下推
5.总结
在《SparkSql连接查询中的谓词下推处理(一)》中,我们介绍了一些基本的概念,并对内连接查询时的一些基本下推规则进行了分析。
本篇文章要介绍的是--外连接查询中的谓词下推规则,这相比内连接中的规则要复杂一些,不过使用简单的表格来进行分析也是可以分析清楚的。先上表:
我们以左外连接查询为例,先总结规矩如下:
接下来对这个表格中的规则进行详细的分析。
1.左表join后条件下推查询语句如下:
前文有提到,对于join后条件,如果放在jo****in操作后执行,是可以作为正确结果进行比对的。那么先对两表进行左连接,结果如下:
然后使用LT.id>1这个join后条件进行过滤,结果如下:
来分析一下LT.id>1下推到左表进行数据过滤的结果,经过LT.id>1过滤后,左表变为:
此时再和右表进行左连接,左表id为2的行,在右表中能找到id为2的行,则连接结果如下:
可见,两种处理方法结果一致。条件下推过滤了左表整整50%的数据(相当牛,虽然只过滤了一条)。究其原因,是因为在SparkSQL中,把以上的查询解析成了如下的子查询:
这是一个非相关子查询,即完全可以先完成子查询,再完成父查询,子查询在查询过程中和外部查询没有关联关系。
2.左表join中条件不下推查询语句如下:
来看看不下推的情况下计算出的正确结果,join过程如下:
第一步:左表id为1的行在右表中能找到相等的id,但是左表的id为1,是不满足第二个join条件(LT.id>1)的,所以左表这一条相当于没有和右表join上,所以左表的值value保留,而右表的value为null(你没满足join中条件没join上还把你的值保留,给我搞个空值?没办法,就是这么任性)。
第二步:左表id为2的行在右表中能找到,而且左表id为2的行的id大于1,两个join条件都满足,所以算是和右表join上了,所以左表和右表的value都保留。最终的查询结果如下:
那么如果把"LT.id>1"这个条件下推到做表,会得到什么结果呢?
首先左表经过"LT.id>1"过滤后,如下: