繁体   English   中英

Spark Scala:多次查询同一张表

[英]Spark Scala: Querying same table multiple times

我正在尝试从同一表(bigTable)查询多个列以生成一些聚合列(column1_sum,column2_sum,column3_count)。 最后,我将所有列连接在一起以形成一个表。

下面的代码

val t1 = bigTable
            .filter($"column10" === value1)
            .groupBy("key1","key2")
            .agg(sum("column1") as "column1_sum")

val t2 = bigTable
            .filter($"column11"===1)
            .filter($"column10" === value1)
            .groupBy("key1","key2")
            .agg(sum("column2") as "column2_sum")

val t3 = bigTable
            .filter($"column10" === value3)
            .groupBy("key1","key2")
            .agg(countDistinct("column3") as "column3_count")

tAll
            .join(t1,Seq("key1","key2"),"left_outer")
            .join(t2,Seq("key1","key2"),"left_outer")
            .join(t3,Seq("key1","key2"),"left_outer")

上面的代码有问题

bigTable是一个巨大的表(它运行成百万行)。 因此,多次查询效率不高。 该查询需要大量时间才能运行。

关于如何以更有效的方式实现相同输出的任何想法? 有没有一种方法可以查询bigTable较少的次数?

非常感谢。

最简单的改进是仅执行单个聚合,将谓词推入CASE ... WHEN ...块中,然后用近似等效值替换countDistinct

tAll
  .groupBy("key1","key2")
  .agg(
    sum(
      when($"column10" === "value1", $"column1")
    ).as("column1_sum"),
    sum(
      when($"column10" === "value1" and $"column11" === 1, $"column2")
    ).as("column2_sum"),
    approx_count_distinct(
      when($"column10" === "value3", $"column3")
    ).as("column3_count"))
  .join(tAll, Seq("key1", "key2"), "right_outer"))

根据所使用的功能以及有关数据分布的专业知识,您还可以尝试使用具有类似CASE ... WHEN ...逻辑的窗口函数替换聚合

import org.apache.spark.sql.expressions.Window

val w = Window
 .partitionBy("key1", "key2")
 .rowsBetween(Window.unboundedPreceding, Window.unboundedFollowing)

tAll
  .withColumn(
    "column1_sum", 
    sum(when($"column10" === "value1", $"column1")).over(w))
 ...

但这通常是不稳定的方法。

您还应该考虑使用分组列对bigTable进行存储:

val n: Int = ???  // Number of buckets
bigTable.write.bucketBy(n, "key1", "key2").saveAsTable("big_table_clustered")

val bigTableClustered = spark.table("big_table_clustered")

我的代码的主要改进之一是查询bigTable一次,而不是问题中提到的多次查询。

我正在尝试的一段代码(我的代码很相似,这只是一个例子):

bigTable
    .filter($"column10" === value1)
    .groupBy("key1", "key2")
    .agg(
      sum("column1") as "column1_sum",
      sum("column2") as "column2_sum",
      countDistinct(when($"column11"===1, col("column3"))) as "column3_count"
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM