我收到一个数据集,并且需要join
和另一个表一起使用。因此,我想到的最简单的解决方案是为另一个表创建第二个数据集并执行joinWith
。
def joinFunction(dogs: Dataset[Dog]): Dataset[(Dog, Cat)] = {
val cats: Dataset[Cat] = spark.table("dev_db.cat").as[Cat]
dogs.joinWith(cats, ...)
}
在这里,我主要关注的是 spark.table("dev_db.cat")
,因为我们好像将所有cat
数据都称为
SELECT * FROM dev_db.cat
,然后在以后执行join
。还是查询优化器将直接执行联接而不引用整个表?有更好的解决方案吗?
答案 0 :(得分:1)
您需要做一个解释,看看是否使用谓词下推。然后,您可以判断您的担忧是否正确。
但是,通常现在,如果不使用复杂的数据类型和/或不明显的数据类型不匹配,则会发生下推。您也可以通过简单的createOrReplaceTempView看到它。参见https://databricks-prod-cloudfront.cloud.databricks.com/public/4027ec902e239c93eaaa8714f173bcfc/3741049972324885/4201913720573284/4413065072037724/latest.html
答案 1 :(得分:1)
以下是针对您的情况的一些建议:
a。。如果您有where
,filter
,limit
,take
等操作,请尝试在合并两个数据集之前应用它们。 Spark无法压低此类筛选器,因此您必须自己减少目标记录的数量。 Here是Spark优化程序的绝佳信息来源。
b。。尝试使用repartition
函数来定位数据集并最小化混洗的数据。重新分区应基于参与join
的密钥,即:
dogs.repartition(1024, "key_col1", "key_col2")
dogs.join(cats, Seq("key_col1", "key_col2"), "inner")
c。。如果您确定较小的数据集可以容纳在内存中(或增加broadcast
的值),请尝试对较小的数据集使用spark.broadcast.blockSize
。这将确保您的Spark程序具有一定的性能提升,因为它将确保同一节点内的两个数据集共存。
如果您不能应用上述任何一项,则Spark无法知道应该排除哪些记录,因此将扫描两个数据集中的所有可用行。