spark jdbc df limit ...它在做什么?

时间:2016-10-03 16:32:02

标签: 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",
  "numPartitions" -> "16",
  "lowerBound" -> "0",
  "upperBound" -> "9999999"
  )).load()

jdbcDF.limit(200).count()

我希望这很快。在具有500K行的表上的类似操作在合理的时间内完成。在这种特殊情况下,表格要大得多(数亿行),但是我认为限制(200)会使它变快吗?我如何计算出花费时间的地方?

1 个答案:

答案 0 :(得分:6)

事实上,spark还没有能够推倒limit谓词。

实际上,在这种情况下发生的事情是它将所有数据拉到火花然后限制和计数。您需要的是在子查询中将其用作表参数。

例如:

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 ticket (SPARK-10899) 以解决此问题,但它已挂了将近一年。

编辑:由于上述JIRA中的问题被标记为重复。您可以继续跟踪问题here - SPARK-12126。 我希望这能回答你的问题。