【发布时间】:2018-06-05 17:29:16
【问题描述】:
我不是 Spark SQL API 专家,也不是底层 RDD 专家。
但是,了解 Catalyst 优化引擎后,我希望 Spark 会尝试尽量减少内存中的工作量。
这是我的情况: 比如说,我有两张桌子
TABLE GenericOperation (ID, CommonFields...)
TABLE SpecificOperation (OperationID, SpecificFields...)
它们都非常庞大(~500M,不是大数据,但在标准应用服务器的内存中作为一个整体存在是不可行的)
也就是说,假设我必须使用 Spark(更大用例的一部分)检索与属于 GenericOperation 的字段上的某些特定条件匹配的所有 SpecificOperation 实例。
这是我正在使用的代码:
val gOps = spark.read.jdbc(db.connection, "GenericOperation", db.properties)
val sOps = spark.read.jdbc(db.connection, "SpecificOperation", db.properties)
val joined = sOps.join(gOps).where("ID = OperationID")
joined.where("CommonField= 'SomeValue'").select("SpecificField").show()
问题是,当涉及到运行上述内容时,我可以从 SQL Profiler 中看到,Spark 不会在数据库上执行连接,而是从 SpecificOperation 检索所有 OperationID,然后我假设它会在内存中运行所有合并。由于没有过滤器适用于SpecificOperation,因此这样的检索会给终端系统带来很多太多的数据。
是否可以将上述内容写成直接要求连接到 dbms? 或者它取决于我不知道的 Spark 的一些神奇配置?
当然,我可以在检索时简单地将连接硬编码为子查询,但在我的情况下这是不可行的:必须在运行时从简单的构建块开始创建语句。因此,我需要从已经建立的两个spark.sql.DataFrame 开始实现这一点
附带说明一下,我使用 Spark 2.3.0 for Scala 2.11 运行它,针对 SQL Server 2016 数据库实例。
【问题讨论】:
-
不完全,但感谢您的建议。我编辑了问题以消除歧义:在我的情况下,我无法在加入之前对逻辑采取行动
-
我不认为它会那样工作。您可以使用 spark.read.jdbc(query) 将查询推送到数据库
标签: scala apache-spark join apache-spark-sql