使用Spark SQL时是否可以将操作连接到数据库?

时间:2018-06-05 17:29:16

标签: scala apache-spark join apache-spark-sql

我不是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数据库实例运行。

1 个答案:

答案 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中受益。