我想使用Spark从Oracle表读取所有记录。
此表假设总共有10,000,000条记录。
以下优化可行吗?
val table = spark.read
.format("jdbc")
.option("driver", "oracle.jdbc.driver.OracleDriver")
.option("url", "jdbc:oracle:thin:@ip:1521:dbname")
.option("user", "")
.option("password", "")
.option("dbtable", s"(select a.*, ROWNUM rownum__rn from tbname a) b")
.option("fetchsize", 100000)
.option("partitionColumn", "rownum__rn")
.option("lowerBound", 0)
.option("upperBound", 10000000)
.option("numPartitions", 10)
.load()
.drop("rownum__rn")
我想知道通过以上代码获得的DataFrame是否与表中的记录一一对应, 也就是说,没有重复和遗漏。
如果上述优化可行,是否意味着多次执行以下语句将以相同顺序返回数据?
select a.*, ROWNUM rownum__rn from tbname a
版本:
答案 0 :(得分:1)
不,如果没有ORDER BY
,您就不能依赖该假设,但也可能(并且很可能)不会以相同的顺序返回行,尤其是对于1000万行。
要么包含ORDER BY
子句,要么-如果您对某些“行号”感兴趣,请使用
select row_number() over (order by deptno, hiredate desc) rn,
dname, loc, ename, job, sal
from your_table
(列名毫无意义,我只是想说明如何做到这一点)。
另外,获取1000万行-您打算如何处理那么多行?您可能不会将它们显示给最终用户,对吗?只是好奇。
答案 1 :(得分:0)
1000万行-为什么保持这么多行的顺序很重要。我认为任何应用程序都不会编写一种逻辑来让所有1000万行都按特定顺序排列。 Spark从基础数据存储中存在的分区读取数据。现在,spark中的读取操作是并行操作,如果在内存中创建了一个分区,则应用程序处理逻辑将启动,并且不会等待所有负载发生。这是将数据异步加载到内存中。
一旦将数据加载到内存中,您还可以考虑使用合并函数或重新分区函数来获得带有火花存储器的分区数。