本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/II48YxGfoursKVvdAXYbVg
做者:李勇
目录:
1.左表 join 后条件下推
2.左表join中条件不下推
3.右表join中条件下推
4.右表join中条件不下推
5.总结segmentfault
在《SparkSql链接查询中的谓词下推处理(一)》中,咱们介绍了一些基本的概念,并对内链接查询时的一些基本下推规则进行了分析。微信
本篇文章要介绍的是--外链接查询中的谓词下推规则,这相比内链接中的规则要复杂一些,不过使用简单的表格来进行分析也是能够分析清楚的。先上表:性能
咱们以左外链接查询为例,先总结规矩以下:spa
接下来对这个表格中的规则进行详细的分析。rem
查询语句以下:get
前文有提到,对于join后条件,若是放在join操做后执行,是能够做为正确结果进行比对的。那么先对两表进行左链接,结果以下:it
而后使用LT.id>1这个join后条件进行过滤,结果以下:class
来分析一下LT.id>1下推到左表进行数据过滤的结果,通过LT.id>1过滤后,左表变为:互联网
此时再和右表进行左链接,左表id为2的行,在右表中能找到id为2的行,则链接结果以下:方法
可见,两种处理方法结果一致。条件下推过滤了左表整整50%的数据(至关牛,虽然只过滤了一条)。究其缘由,是由于在SparkSQL中,把以上的查询解析成了以下的子查询:
这是一个非相关子查询,即彻底能够先完成子查询,再完成父查询,子查询在查询过程当中和外部查询没有关联关系。
查询语句以下:
来看看不下推的状况下计算出的正确结果,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"过滤后,以下:
此时再和右表链接,左表id为2的行在右表中能找到,且知足"LT.id = RT.id AND LT.id > 1"这个join中条件,因此两表的value都被保留。左表中已经没有数据了,查询结束,查询结果以下:
这个查询结果和不下推的正确结果不一致,是个错误的结果,因此左表join中条件是不能下推动行数据过滤的。分析缘由:主要是由于join中条件和join后条件对结果的处理方式不一样,前者在不知足join条件时会保留一部分结果,然后者在不知足条件时任何东西都不保留。
查询语句以下:
如今把RT.id>1这个右表join后条件下推,来过滤右表,过滤后以下:
而后左表再和右表进行左链接,流程以下:
第一步:左表id为1的行在右表中没有,此时左表值保留,右表为null;
第二步:左表id位2的行在右表中有,而且RT.id大于1,两个join条件都知足,则左表和右表的值都保留。查询结果以下:
那么若是不下推(为了获得正确结果),来看看结果,流程以下:
第一步:左表id为1的行在右表中有,可是不知足第二个join条件,因此这行算是没join上,因此左表数据保留,右表为null;
第二步:左表id为2的行在右表中有,也知足第二个join条件,因此左右表的数据都保留。
可见,右表join中条件下推不下推,结果同样,因此,干嘛不下推?能够过滤掉一半的数据呢。SparkSQL中的等价处理语句是:
能够看出,也是解析成了一个非相关子查询来处理的。
这个应该是最违反常规理解的查询了,查询语句以下:
首先来看,join后条件不下推的状况,流程以下:
第一步:左表id为1的行在右表中能够找到,可是此时仅仅知足join条件,在使用where条件判断这条链接后数据时,发现右表的id不知足RT.id>1的条件,因此这条join结果不保留(注意:这里是不保留,全都不保留,左表右表都不保留,要跟上边的没join上而右表的值保留为null的状况区别开,这也是关键所在);
第二步:左表id为2的行和右表id为2的行join上了,同时也知足RT.id>1的where条件。
这是一条符合语义的正确的查询结果。
好了,接下来看看右表join后条件下推的状况:
第一步:使用RT.id>1过滤右表,过滤后右表只剩一行id为2的行;
第二步:左表id为1的行在过滤后的右表中没有,此时左表值保留,右表值为null;
第三步:左表id为2的行在右表中有,此时左表值保留,右表值也保留。
结果以下:
很明显这实际上是一个错误的结果。
至此,左链接查询的四条规则分析完了。能够看出,在SparkSQL中对于外链接查询时的过滤条件,并不能在全部状况下都用来进行数据源的过滤,若是使用得当会极大的提高查询性能,若是使用不当,则会产生错误的查询结果,而这种错误结果又不易发觉,因此使用时要格外当心。
更多内容敬请关注 vivo 互联网技术 微信公众号
注:转载文章请先与微信号:labs2020 联系。