[英]spark, scala & jdbc - how to limit number of records
有没有办法限制使用 spark sql 2.2.0 从 jdbc 源获取的记录数?
我正在处理将 > 200M 的大量记录从一个 MS Sql Server 表移动(和转换)到另一个表的任务:
val spark = SparkSession
.builder()
.appName("co.smith.copydata")
.getOrCreate()
val sourceData = spark
.read
.format("jdbc")
.option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver")
.option("url", jdbcSqlConnStr)
.option("dbtable", sourceTableName)
.load()
.take(limit)
当它工作时,它显然首先从数据库中加载所有 200M 记录,首先花费 18 分钟,然后返回我想要用于测试和开发目的的有限数量的记录。
切换 take(...) 和 load() 会产生编译错误。
我很欣赏有多种方法可以将示例数据复制到较小的表、使用 SSIS 或替代 etl 工具。
我真的很好奇是否有办法使用 spark、sql 和 jdbc 来实现我的目标。
要限制下载的行数,可以使用 SQL 查询代替“dbtable”中的表名。 文档中的说明。
在查询中可以指定“where”条件,例如,使用服务器特定的功能来限制行数(如 Oracle 中的“rownum”)。
这种方法对关系数据库有点不利。 spark的加载功能会请求你的全表,存储在内存/磁盘中,然后进行RDD转换和执行。
如果你想做一个探索性的工作,我会建议你在第一次加载时存储这些数据。 有几种方法可以做到这一点。 拿你的代码做这样的事情:
val sourceData = spark
.read
.format("jdbc")
.option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver")
.option("url", jdbcSqlConnStr)
.option("dbtable", sourceTableName)
.load()
sourceData.write
.option("header", "true")
.option("delimiter", ",")
.format("csv")
.save("your_path")
这将允许您将数据以 CSV 格式保存在本地计算机中,这是您可以使用任何语言进行探索的最常见格式。 每次你想加载它时,从这个文件中获取这些数据。 如果您想要实时分析,或任何其他类似的东西。 我建议您使用数据转换构建一个管道以更新另一个存储。 每次都使用这种方法来处理从数据库加载的数据并不好。
我没有测试过这个,但你应该尝试使用limit
而不是take
。 take
电话head
具有下列注意事项在幕后:
仅当预期结果数组较小时才应使用此方法,因为所有数据都已加载到驱动程序的内存中。
而limit
导致 LIMIT 被推入 sql 查询,因为它是一个懒惰的评估:
这个函数和
head
的区别在于head
是一个 action 并返回一个数组(通过触发查询执行),而limit
返回一个新的 Dataset。
如果您想要数据而不先将其拉入,那么您甚至可以执行以下操作:
...load.limit(limitNum).take(limitNum)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.