spark通過(guò)jdbc可以從oracle中直接讀取數(shù)據(jù),返回dataframe。有時(shí)由于數(shù)據(jù)量較大酒甸,我們可以采用分區(qū)方式通過(guò)jdbc多線程并行從oracle中讀取數(shù)據(jù)。
- oracle中的數(shù)據(jù)如下
TIME字段是年月赋铝,為字符串類型插勤,ACCOUNT_BOOK為INT類型
image.png
object OraclePartitionReadTest {
def main(args: Array[String]): Unit = {
val spark = spark = SparkSession.builder()
.appName(appName)
.master("local")
.getOrCreate()
// 1. 通過(guò)jdbc從oracle中直接讀取數(shù)據(jù),不分區(qū)
val dfReadFromOra = spark.read.jdbc(url, "tableName", properties)
println(dfReadFromOra.count())
/* 2. 通過(guò)設(shè)定字段的條件來(lái)劃分分區(qū)。
如下把TIME字段饮六,按日期區(qū)間劃分為兩個(gè)子區(qū)間,[2018-01苛蒲,2018-12]為一個(gè)區(qū)間卤橄,[2019-01,2019-12]為一個(gè)區(qū)間臂外。定義一個(gè)字符串?dāng)?shù)組來(lái)存放區(qū)間窟扑,區(qū)間個(gè)數(shù)即為spark從oracle讀取數(shù)據(jù)時(shí)的分區(qū)個(gè)數(shù)。
*/
val whereClause = Array("TIME>='2018-01' AND TIME <= '2018-13'", "TIME >= '2019-01' AND TIME <= '2019-12'")
val dfReadFromOraByPartUseWhereClause = spark.read.jdbc(url,"tableName", whereClause, oracleProp)
println(dfReadFromOraByPartUseWhereClause.rdd.getNumPartitions) // 打印分區(qū)個(gè)數(shù)
println(dfReadFromOraByPartUseWhereClause.count())
/* 3. 針對(duì)數(shù)值類型的字段ACCOUNT_BOOK漏健,設(shè)定上邊界和下邊界嚎货,并指定分區(qū)個(gè)數(shù),jdbc方法會(huì)根據(jù)這三個(gè)條件劃分分區(qū)從oracle讀取數(shù)據(jù)蔫浆。
*/
val dfReadFromOraByPartitionUseBound = spark.read.jdbc(url, "tableName", "ACCOUNT_BOOK", 2000, 2500, 5殖属,oracleProp)
println(dfReadFromOraByPartitionUseBound .rdd.getNumPartitions) // 打印分區(qū)個(gè)數(shù)
println(dfReadFromOraByPartitionUseBound.count())
}
}
通過(guò)驗(yàn)證,采用分區(qū)的方式從oracle中讀取數(shù)據(jù)瓦盛,提升讀取數(shù)據(jù)的效果很明顯洗显。 分區(qū)個(gè)數(shù)根據(jù)情況而定,如果分區(qū)個(gè)數(shù)較大原环,可能會(huì)影響oracle數(shù)據(jù)庫(kù)的正常運(yùn)行挠唆。百十個(gè)分區(qū)一般不會(huì)有問(wèn)題。