Scala Spark中针对配置单元表中存储的图的长线性查询

Scala Spark中针对配置单元表中存储的图的长线性查询,scala,apache-spark,graph,apache-spark-sql,catalyst-optimizer,Scala,Apache Spark,Graph,Apache Spark Sql,Catalyst Optimizer,假设我有一个图G和以下查询: x y z w q r s (?a)--(?b)--(?c)--(?d)--(?e)--(?f)--(?g)--(?h) 其中,{a,?b,?c,…,h}是变量,{x,y,z,w,q,r,s}是弧标签 在存储级别,每个标签有一个表,但两个标签的组合也有一个表。 例如,我可能有一个带有列|a | b |的表x,但我也有一个带有列|a | b | c的表xy。是的,我有多余的桌子 基于此设置,我有两个问题: a)

假设我有一个图G和以下查询:

     x     y     z     w     q     r    s
(?a)--(?b)--(?c)--(?d)--(?e)--(?f)--(?g)--(?h)
其中,{a,?b,?c,…,h}是变量,{x,y,z,w,q,r,s}是弧标签

在存储级别,每个标签有一个表,但两个标签的组合也有一个表。 例如,我可能有一个带有列|a | b |的表x,但我也有一个带有列|a | b | c的表xy。是的,我有多余的桌子

基于此设置,我有两个问题:

a) 我需要找到表,以便它们之间的连接能够导致最佳执行时间(最小)。 设{xy zw,q,rs}为上述示例中的表

b) 我必须按照给定的顺序执行连接,因此我需要找到该顺序,例如:(rs⨝ q)⨝ (zw)⨝ xy)(⨝ 是一个自然连接)

假设我知道要使用哪些表,即我已经解决了a),我的问题是如何处理第二个表。Spark API允许我在一行中执行所有连接:

val res1 = xy.join(zw, Seq("c")).join(q, Seq("e")).join(rs, Seq("f"))
但我也可以在几行中执行它:

val tmp1 = xy.join(zw, Seq("c"))

val tmp2 = q.join(rs, Seq("f"))

val res2 = tmp1.join(tmp2, Seq("e"))
在我的实验中,res1.count和res2.count(多次运行的avegare)的执行时间是不同的。树的构建方式似乎对执行有影响

1) 我可以使用哪种策略来构建一棵树,从而在Spark中获得最佳执行时间

2) 如果每个不同的树似乎导致不同的性能,那么查询优化器wrt的角色是什么。连接顺序。它似乎什么也没做,特别是在我将所有连接都放在一行代码中的情况下:

val res1 = xy.join(zw, Seq("c")).join(q, Seq("e")).join(rs, Seq("f"))

在一个案例中,我可以有一个合理的执行时间。另一个是暂停。Catalyst什么都没做吗

Spark API允许我在一行中执行所有连接:

但我也可以在几行中执行它:

val tmp1 = xy.join(zw, Seq("c"))

val tmp2 = q.join(rs, Seq("f"))

val res2 = tmp1.join(tmp2, Seq("e"))
不对。此时不执行,但仅在执行操作时执行。您展示了使用Scala中创建相同查询计划的高级运算符编写相同计算图的不同方法

1) 我可以使用哪种策略来构建一棵树,从而在Spark中获得最佳执行时间

这就是所谓的Catalyst Optimizer(而不是您)的目的。您可能希望探索基于成本的JoinReorder逻辑优化和JoinSelection执行计划策略,这些策略负责确保联接的最佳性能

JoinSelection执行规划策略由SparkPlanner用于将
Join
逻辑运算符规划为受支持的连接物理运算符之一

CostBasedJoinReorder是基于成本的优化中用于重新排序联接的逻辑优化

如果表的大小很重要,考虑基于成本的优化(CBO)。你应该看到不同。您必须使用表(而不是任何关系)并对统计数据执行

ANALYZE TABLE COMPUTE STATISTICS
命令

Catalyst什么都没做吗


它应该优化连接。解释查询计划以了解更多详细信息。

你好,Jacek,谢谢你的回答。是的,我知道懒惰的操作。我查看了相应的res1、res2和res3的计划(优化的逻辑计划),它正好反映了我用API编写它的方式,也就是说,似乎没有进行连接重新排序。Catalyst没有优化有什么原因吗?我目前正在研究spark 2.4.3(单机版)和2.2.2(集群版),这两个系统中都存在同样的情况。顺便问一下,您能提供查询计划吗?有反对2.4.4的理由吗?这是最新最棒的。谢谢!是的,我会尝试使用CBO强制执行,看看会发生什么。这些计划包含很多文本。你的意思是我应该把它们附加到某个地方,还是重新编辑我的问题并添加一个高级代表性描述?我还没有尝试过2.4.4,因为我需要与以前的实验结果相比较,但我期待着尝试它!附加带有足够信息的日志。最接近真实用例越好(但噪音越小越好)。谢谢。事实上,我没有提到这些DFs都是通过读取单个大型配置单元表生成的,因为我认为这个细节不相关。看来我错了。由于它的某些列包含数组,这意味着我无法获得所有DFs的统计信息,Catalyst将无法优化联接的顺序。这意味着,我需要实现自己的优化器,它解决了2)。