这个问题适用于Spark,但我假设(?)它可能更常见于任何SQL表连接。
假设我们有表A和B.然后我们发出这个命令:
select a.* from a inner join b on a.col1 - b.col1 <= 0.5
在幕后,首先创建一个笛卡尔积,然后根据a.col1 - b.col1&lt; = 0.5的条件进行过滤。或者评估表之间的每个行组合,然后再返回标准是的,生成的行返回了吗?
答案 0 :(得分:1)
是。连接条件(不是基于值的相等性(用户定义的函数调用的结果,对来自不同表的列计算的值以及非相等性比较运算符)无法优化,并且被评估为笛卡尔积,然后进行选择。
如果您检查生成的执行计划,很容易确认。例如:
import org.apache.spark.sql.functions._
spark.range(1000).select(rand() as "col1").createOrReplaceTempView("a")
spark.range(1000).select(rand() as "col1").createOrReplaceTempView("b")
spark.sql("select a.* from a inner join b on a.col1 - b.col1 <= 0.5").explain
// == Physical Plan ==
// *Project [col1#9]
// +- BroadcastNestedLoopJoin BuildRight, Inner, ((col1#9 - col1#16) <= 0.5)
// :- *Project [rand(3279117551830311353) AS col1#9]
// : +- *Range (0, 1000, step=1, splits=4)
// +- BroadcastExchange IdentityBroadcastMode
// +- *Project [rand(-3185472069145487350) AS col1#16]
// +- *Range (0, 1000, step=1, splits=4)
同样如果你禁用广播联接:
spark.conf.set("spark.sql.autoBroadcastJoinThreshold", -1)
spark.sql("select a.* from a inner join b on a.col1 - b.col1 <= 0.5").explain
// == Physical Plan ==
// *Project [col1#9]
// +- CartesianProduct ((col1#9 - col1#16) <= 0.5)
// :- *Project [rand(3279117551830311353) AS col1#9]
// : +- *Range (0, 1000, step=1, splits=4)
// +- *Project [rand(-3185472069145487350) AS col1#16]
// +- *Range (0, 1000, step=1, splits=4)