簡體   English   中英

spark、scala 和 jdbc - 如何限制記錄數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM