Aja*_*mma 6 java performance scala apache-spark apache-spark-sql
我需要比较我的spark应用程序中的两个数据帧.我通过了以下帖子. 如何获取两个DataFrame之间的差异?
但是,我不明白为什么这个方法在最佳答案中
df1.unionAll(df2).except(df1.intersect(df2))
Run Code Online (Sandbox Code Playgroud)
比问题中的更好
df1.except(df2).union(df2.except(df1))
Run Code Online (Sandbox Code Playgroud)
谁能解释一下?根据我的理解,后者使用两个较小的数据集,以前使用大型数据集.是因为后者作为联盟的一部分而独特吗?即使这样,如果两个数据帧更可能是具有相同记录的情况,我们在后一种情况下处理一个小数据集.
首先,unionAll从 Spark 第 2 版开始已弃用。请union改为使用,就像您在第二个片段中所做的那样。
其次,在您所引用的问题的答案中,没有任何信息表明第一段代码更好。我准备了这样一个场景。对我来说,第一个花了 31 秒,第二个花了 18 秒。在我的例子中,df1有大约 300 万行和df2大约 100 万行,每行 5 列。
如果我们现在分析第一个查询的优化逻辑执行计划:
== Optimized Logical Plan ==
GlobalLimit 21
+- LocalLimit 21
+- Aggregate [_c0#10, _c1#11, _c2#12, _c3#13, _c4#14], [cast(_c0#10 as string) AS _c0#67, cast(_c1#11 as string) AS _c1#68, cast(_c2#12 as string) AS _c2#69, cast(_c3#13 as string) AS _c3#70, cast(_c4#14 as string) AS _c4#71]
+- Join LeftAnti, (((((_c0#10 <=> _c0#52) && (_c1#11 <=> _c1#53)) && (_c2#12 <=> _c2#54)) && (_c3#13 <=> _c3#55)) && (_c4#14 <=> _c4#56))
:- Union
: :- Relation[_c0#10,_c1#11,_c2#12,_c3#13,_c4#14] csv
: +- Project [_c0#30, _c1#31, _c2#32, _c3#33, cast(_c4#34 as double) AS _c4#40]
: +- Relation[_c0#30,_c1#31,_c2#32,_c3#33,_c4#34] csv
+- Aggregate [_c0#52, _c1#53, _c2#54, _c3#55, _c4#56], [_c0#52, _c1#53, _c2#54, _c3#55, _c4#56]
+- Join LeftSemi, (((((_c0#52 <=> _c0#30) && (_c1#53 <=> _c1#31)) && (_c2#54 <=> _c2#32)) && (_c3#55 <=> _c3#33)) && (_c4#56 <=> _c4#46))
:- Relation[_c0#52,_c1#53,_c2#54,_c3#55,_c4#56] csv
+- Project [_c0#30, _c1#31, _c2#32, _c3#33, cast(_c4#34 as double) AS _c4#46]
+- Relation[_c0#30,_c1#31,_c2#32,_c3#33,_c4#34] csv
Run Code Online (Sandbox Code Playgroud)
我们可以看到,有Union和Join(交集)同时运行,这是非常昂贵的,特别是Union,而对于第二个查询:
== Optimized Logical Plan ==
GlobalLimit 21
+- LocalLimit 21
+- Union
:- LocalLimit 21
: +- Aggregate [_c0#10, _c1#11, _c2#12, _c3#13, _c4#14], [cast(_c0#10 as string) AS _c0#120, cast(_c1#11 as string) AS _c1#121, cast(_c2#12 as string) AS _c2#122, cast(_c3#13 as string) AS _c3#123, cast(_c4#14 as string) AS _c4#124]
: +- Join LeftAnti, (((((_c0#10 <=> _c0#30) && (_c1#11 <=> _c1#31)) && (_c2#12 <=> _c2#32)) && (_c3#13 <=> _c3#33)) && (_c4#14 <=> _c4#98))
: :- Relation[_c0#10,_c1#11,_c2#12,_c3#13,_c4#14] csv
: +- Project [_c0#30, _c1#31, _c2#32, _c3#33, cast(_c4#34 as double) AS _c4#98]
: +- Relation[_c0#30,_c1#31,_c2#32,_c3#33,_c4#34] csv
+- LocalLimit 21
+- Aggregate [_c0#30, _c1#31, _c2#32, _c3#33, _c4#104], [cast(_c0#30 as string) AS _c0#130, cast(_c1#31 as string) AS _c1#131, cast(_c2#32 as string) AS _c2#132, cast(_c3#33 as string) AS _c3#133, cast(_c4#104 as string) AS _c4#134]
+- Join LeftAnti, (((((_c0#30 <=> _c0#10) && (_c1#31 <=> _c1#11)) && (_c2#32 <=> _c2#12)) && (_c3#33 <=> _c3#13)) && (_c4#104 <=> _c4#14))
:- Project [_c0#30, _c1#31, _c2#32, _c3#33, cast(_c4#34 as double) AS _c4#104]
: +- Relation[_c0#30,_c1#31,_c2#32,_c3#33,_c4#34] csv
+- Relation[_c0#10,_c1#11,_c2#12,_c3#13,_c4#14] csv
Run Code Online (Sandbox Code Playgroud)
有两个LeftAnti同时运行(相对恭维)。这占用的空间更少并且效率更高。这可以在 SparkUI 中看到:
在第一种情况下,阶段 7 -Union成本最高,而在第二种情况下,阶段 42 和 41(上图)相对较快。