SparkSQL 加入父/子数据集

Posted

技术标签:

【中文标题】SparkSQL 加入父/子数据集【英文标题】:SparkSQL joining parent/child datasets 【发布时间】:2017-10-12 17:42:59 【问题描述】:

我正在使用 SparkSQL 2.2.0 从 Cassandra 加载数据并将其索引到 Elasticsearch。我拥有的数据由客户(第一张表people)和订单(第二张表orders)组成。 表订单有一个列 person_id 指向相应的客户。 我需要查询(并稍后在 Elasticsearch 中编制索引)people 表和 orders,以便我可以为每个客户获取她购买的订单数量。 我想出的最简单的方法是将这两个表读入org.apache.spark.sql.Dataset<Row>s 并在person_id 列上进行join。然后我groupBy(person_id). 这给了我一个包含两列的数据集:person_idcount,我必须将它们与people 表结合起来,这样我就可以对其他人的数据进行计数。

Dataset<Row> peopleWithOrders = people.join(orders, people.col("id").equalTo(orders.col("person_id")), "left_outer");

Dataset<Row> peopleOrdersCounts = peopleWithOrders.groupBy("id").count().withColumnRenamed("id", "personId");

Dataset<Row> peopleWithOrderCounts = people.join(personsOrdersCounts, people.col("id").equalTo(peopleOrdersCounts.col("personId")), "left_outer")
            .withColumnRenamed("count", "nbrOfOrders")
            .select("id", "name", "birthDate", "nbrOfOrders");

people 表有 1_000_000 行,orders 有一个 2_500_000。每个客户有 2 或 3 个订单。 我正在使用带有 2.2 GHz Intel Core i7 处理器和 16 GB 1600 MHz DDR3 内存的 MAC Book pro。所有 Cassandra、Spark 2.2 master 和(单个)worker 都在同一台机器上。 这 3 个连接需要 15 到 20 秒。 我的问题是:是否有一些性能提升空间。 Window Aggregate Functions 是否有好处,因为我在日志中看到了 ShuffleMapTask。

提前致谢

【问题讨论】:

【参考方案1】:

我认为第一步是不必要的。你可以这样做:

Dataset<Row> peopleOrdersCounts = orders.groupBy("person_id").count();

Dataset<Row> peopleWithOrderCounts = people.join(personsOrdersCounts, people.col("id").equalTo(peopleOrdersCounts.col("personId")), "left_outer")
            .withColumnRenamed("count", "nbrOfOrders")
            .select("id", "name", "birthDate", "nbrOfOrders");

我希望这会有所帮助。

【讨论】:

是的,这是真的。我的错。但这仍然“相对较慢”(ab 16s)。我想知道“窗口聚合函数”是否有帮助,或者这是正常的方法 据我所知,这是这样做的。特别是在“分组依据”的情况下。您可以查看用户定义的聚合函数(UDAF),但即使是针对特定情况的。是否有任何其他操作可能会减慢这一速度?

以上是关于SparkSQL 加入父/子数据集的主要内容,如果未能解决你的问题,请参考以下文章

当子窗口具有递增值时如何增加父组编号?

如何加入两个镶木地板数据集?

Google BigQuery SQL:使滚动平均子查询或加入对大型数据集更有效

SparkSQL + Java:使用数据集时将 Pojo 转换为表格格式

SparkSQL:如何在从数据库加载数据集时指定分区列

如何使用自动生成的标识密钥更新数据集父子表?