我不是Spark SQL API的专家,也不是基础RDD专家。
但是,了解Catalyst优化引擎后,我希望Spark能够尽量减少内存工作量。
这是我的情况: 我有,比方说,两个表
TABLE GenericOperation (ID, CommonFields...)
TABLE SpecificOperation (OperationID, SpecificFields...)
它们都非常庞大(~500M,不是大数据,但在标准应用程序服务器中作为整体存储在内存中是不可行的)
也就是说,假设我必须使用Spark(大型用例的一部分)检索所有SpecificOperation
个实例,这些实例在属于GenericOperation
的字段上匹配某些特定条件。
这是我正在使用的代码:
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事件探查器看到Spark不会在数据库上执行连接,而是从OperationID
检索所有SpecificOperation
,然后我假设它将在内存中运行所有合并。由于SpecificOperation
上没有适用过滤器,因此此类检索会为终端系统带来很多太多数据。
是否可以编写以上内容以便直接向dbms请求连接? 或者它取决于我不知道的Spark的一些神奇配置?
当然,我可以在检索时简单地将连接硬编码为子查询,但在我的情况下这是不可行的:语句必须在运行时从简单的构建块开始创建。因此,我需要从已经构建的两个spark.sql.DataFrame
作为旁注,我正在使用Spark 2.3.0 for Scala 2.11,针对SQL Server 2016数据库实例运行。
答案 0 :(得分:0)
是否可以编写以上内容以便直接向dbms请求连接?或者它取决于我不知道的Spark的一些神奇配置?
排除静态生成的查询(In Apache Spark 2.0.0, is it possible to fetch a query from an external database (rather than grab the whole table)?),Spark不支持join
下推。只能将谓词和选择委托给源。
没有神奇的配置或代码甚至可以支持这种类型的过程。
通常,如果服务器可以处理连接,则数据通常不足以从Spark中受益。