为什么在SQL查询中使用UDF会导致笛卡尔积?

时间:2015-10-05 15:18:19

标签: sql apache-spark apache-spark-sql

我看到Databricks-Question并且不明白

  1. 为什么使用UDF会导致笛卡尔积而不是完整的外连接?显然,笛卡尔积将比全外连接(Joins是一个例子)要多得多,这是一个潜在的表现 命中。
  2. Databricks-Question中给出的示例中,是否可以强制使用笛卡尔积的外连接?
  3. 在此处引用Databricks-Question

      

    我有一个使用SQLContext执行的Spark Streaming应用程序   关于流数据的SQL语句。当我在中注册自定义UDF时   Scala,流应用程序的性能下降   显著。详情如下:

         

    声明1:

         

    Select col1, col2 from table1 as t1 join table2 as t2 on t1.foo = t2.bar

         

    声明2:

         

    Select col1, col2 from table1 as t1 join table2 as t2 on equals(t1.foo,t2.bar)

         

    我使用SQLContext注册自定义UDF,如下所示:

         

    sqlc.udf.register("equals", (s1: String, s2:String) => s1 == s2)

         

    在相同的输入和Spark配置上,St​​atement2的性能   与Statement1相比,显着更差(接近100倍)。

1 个答案:

答案 0 :(得分:7)

  

为什么使用UDF会导致笛卡尔积而不是完整的外连接?

使用UDF需要笛卡尔积的原因非常简单。由于您传递具有可能无限域和非确定性行为的任意函数,因此确定其值的唯一方法是传递参数并进行求值。这意味着您只需检查所有可能的对。

另一方面,简单的平等具有可预测的行为。如果您使用t1.foo = t2.bar条件,则可以分别按t1t2排列foobar行,以获得预期结果。

准确地说,关系代数外连接实际上是使用自然连接表示的。除此之外的任何事情都只是一种优化。

  

任何强制外部连接超过笛卡尔积的方法

不是,除非你想修改Spark SQL引擎。