Apache spark 火花jdbc df限制。。。它在干什么?

Apache spark 火花jdbc df限制。。。它在干什么?,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我正在努力学习如何了解Spark内部的情况,以下是我目前的困惑。我试图将Oracle表中的前200行读入Spark: val jdbcDF = spark.read.format("jdbc").options( Map("url" -> "jdbc:oracle:thin:...", "dbtable" -> "schema.table", "fetchSize" -> "5000", "partitionColumn" -> "my_row_id",

我正在努力学习如何了解Spark内部的情况,以下是我目前的困惑。我试图将Oracle表中的前200行读入Spark:

val jdbcDF = spark.read.format("jdbc").options(
  Map("url" -> "jdbc:oracle:thin:...",
  "dbtable" -> "schema.table",
  "fetchSize" -> "5000",
  "partitionColumn" -> "my_row_id",
  "numPartitions" -> "16",
  "lowerBound" -> "0",
  "upperBound" -> "9999999"
  )).load()

jdbcDF.limit(200).count()

我希望这会相当快。对具有500K行的表执行类似操作将在合理的时间内完成。在这种特殊情况下,表要大得多(数亿行),但我认为限制(200行)会使它变快吗?我该如何计算出它在哪里花费时间呢?

事实上,spark还没有能力降低
限制
谓词

所以实际上,在这个案例场景中发生的事情是,它将所有的数据拉到spark,然后限制和计数。您需要的是在子查询中将其用作表参数

e、 g:

val jdbcDF = spark.read.format("jdbc").options(
  Map("url" -> "jdbc:oracle:thin:...",
  "dbtable" -> "(select * from schema.table limit 200) as t",
  "fetchSize" -> "5000",
  "partitionColumn" -> "my_row_id",
  "numPartitions" -> "16",
  "lowerBound" -> "0",
  "upperBound" -> "9999999"
  )).load()
因此,它花费时间的主要目的是将所有数据收集起来

您还可以在子查询中动态传递限制:

val n : Int = ???

val jdbcDF = spark.read.format("jdbc").options(
  Map("url" -> "jdbc:oracle:thin:...",
  "dbtable" -> s"(select * from schema.table limit $n) as t",
  "fetchSize" -> "5000",
  "partitionColumn" -> "my_row_id",
  "numPartitions" -> "16",
  "lowerBound" -> "0",
  "upperBound" -> "9999999"
  )).load()
解决这个问题的工作正在进行中,但已经搁置了将近一年

编辑:因为上述JIRA中的问题被标记为重复。您可以继续跟踪问题。
我希望这能回答您的问题。

谢谢,它回答了实质性的部分(这很有意义……Spark应该如何知道如何限制特定RDBMS中的结果?)。老实说,我没有深入研究这个主题,但我知道它必须在数据源catalyst中实现。但是CatalystAPI仍然是一个谜,没有太多的相关文档。因此,我恐怕无法回答谓词应该如何具体下推的问题。截至2017年11月,我可以确认
Spark 2.2.0
现在能够将
limit
谓词下推到
MySQL
中,我通过在
SQL
查询(字符串)本身中包含
limit
子句来实现这一点。不确定if是否按照这里提到的方式工作。这与@y2k shubham:)不同。我们讨论的是您在spark方面定义的谓词。