SQL是从右向左求值还是从左向右求值?

SQL是从右向左求值还是从左向右求值?,sql,apache-spark,apache-spark-sql,Sql,Apache Spark,Apache Spark Sql,我有一个SQL查询,如下所示- A left JOIN B Left Join C Left JOIN D 假设表A是一个大表,而表B、C、D是小表 Will Spark join将执行如下操作- A和B以及随后的结果将与C和D合并 或者 Spark将自动优化,即它将加入B、C和D,然后 结果将与A合并 我的问题是什么是执行顺序或联接求值?它是从左到右还是从右到左?Spark可以优化连接顺序,前提是它可以访问有关这些连接的复杂性的信息 例如,若那个些是拼花表或缓存的数据帧,那个么它对表的总计数

我有一个SQL查询,如下所示-

A left JOIN B Left Join C Left JOIN D
假设表A是一个大表,而表B、C、D是小表

Will Spark join将执行如下操作- A和B以及随后的结果将与C和D合并

或者

Spark将自动优化,即它将加入B、C和D,然后 结果将与A合并


我的问题是什么是执行顺序或联接求值?它是从左到右还是从右到左?

Spark可以优化连接顺序,前提是它可以访问有关这些连接的复杂性的信息

例如,若那个些是拼花表或缓存的数据帧,那个么它对表的总计数进行了估计,并且可以对连接顺序进行重新排序以降低成本。如果表是jdbc数据帧,则Spark可能没有关于行计数的信息

Spark Query Optimizer还可以选择不同的联接类型,以防有统计信息,例如,它可以广播所有较小的表,并运行广播哈希联接而不是排序合并联接

如果统计数据不可用,那么它将按照SQL查询中的顺序进行,例如从左到右

更新:

我最初没有注意到查询中的所有连接都是外部连接left与left-OUTER等价

通常,外部联接不能被重新排序,因为这会改变查询的结果。我说的正常是因为有时候Spark优化器可以将外部连接转换为内部连接,例如,如果您有一个WHERE子句过滤掉空值-

为了回答的完整性,连接的重新排序由两个不同的代码路径驱动,具体取决于Spark CBO是否启用Spark.sql.CBO.enabled首先出现在Spark 2.2中,默认情况下处于关闭状态。如果spark.sql.cbo.enabled=true和spark.sql.cbo.joinReorder.enabled=true,则默认情况下也会关闭,并且统计信息可通过ANALYZE TABLE手动获取。。计算统计信息,然后根据我上面提到的连接的估计基数重新排序

在CBO示例中,证明重新排序仅适用于内部联接

更新2:示例查询显示外部联接的重新排序会产生不同的结果,因此外部联接永远不会重新排序:


连接的解释顺序对于内部连接并不重要。但是,对于外部联接可能很重要

您的逻辑相当于:

FROM ((A LEFT JOIN
       B
      ) ON . . . LEFT JOIN
      C
      ON . . . LEFT JOIN
     )
     D
     ON . . .
考虑左联接链的最简单方法是,它们使第一个表中的所有行和后续表中的列不匹配


请注意,这是对代码的解释。SQL优化器可以按任意顺序重新排列联接,以获得相同的结果集,尽管使用外部联接的可能性通常比使用内部联接的可能性小。

这是关于Spark的。@thebluephantom。这不会有什么区别,除非Spark在这方面有意避免遵循标准SQL。它已经做到了,并且落后了。@BluePhantom Gordon是对的。。外部联接不会重新排序。我错过了Q离开的机会。。更新了我的答案。@Tagar但太无火花的答案,以及我的评论?我将在新的一年里考试。还取决于来自持久配置单元源的reorder definition.cached daraframe。如果你继续在内存中工作,例如过滤,joinjng,我不太确定它是否有效。请参阅过时或仍然有效