簡體   English   中英

在 Spark SQL 中將多個小表與大表連接的最佳方法

[英]Best way to join multiples small tables with a big table in Spark SQL

我正在使用 spark sql 連接多個表。 其中一張桌子很大,其他桌子很小(10-20 條記錄)。 我真的想使用包含鍵值對的其他表替換最大表中的值。

即大表:

| Col 1 | Col 2 | Col 3 | Col 4 | ....
--------------------------------------
| A1    | B1    | C1    | D1    | ....
| A2    | B1    | C2    | D2    | ....
| A1    | B1    | C3    | D2    | ....
| A2    | B2    | C3    | D1    | ....
| A1    | B2    | C2    | D1    | ....
.
.
.
.
.

表2:

| Col 1 | Col 2 
----------------
| A1    | 1a    
| A2    | 2a    

表3:

| Col 1 | Col 2 
----------------
| B1    | 1b    
| B2    | 2b  

表3:

| Col 1 | Col 2 
----------------
| C1    | 1c    
| C2    | 2c  
| C3    | 3c

表4:

| Col 1 | Col 2 
----------------
| D1    | 1d    
| D2    | 2d  

預期表是

| Col 1 | Col 2 | Col 3 | Col 4 | ....
--------------------------------------
| 1a    | 1b    | 1c    | 1d    | ....
| 2a    | 1b    | 2c    | 2d    | ....
| 1a    | 1b    | 3c    | 2d    | ....
| 2a    | 2b    | 3c    | 1d    | ....
| 1a    | 2b    | 2c    | 1d    | ....
.
.
.
.
.

我的問題是; 這是加入表格的最佳方式 (認為​​有100個或更多的小表) 1)收集小數據框,將其轉換為地圖,廣播地圖和轉換大數據框只需一步

bigdf.transform(ds.map(row => (small1.get(row.col1),.....)

2)廣播表並使用選擇方法進行連接。

spark.sql("
       select * 
       from bigtable
       left join small1 using(id1) 
       left join small2 using(id2)")

3) 廣播表和 Concatenate multiples joins

bigtable.join(broadcast(small1), bigtable('col1') ==small1('col1')).join...

提前致謝

你可能會這樣做:

  1. 廣播所有小表(通過設置spark.sql.autoBroadcastJoinThreshold自動完成,略優於小表行數)
  2. 運行一個連接大表的 sql 查詢,例如

    val df = spark.sql(" select * from bigtable left join small1 using(id1) left join small2 using(id2)")

編輯:在 sql 和 spark "dataframe" 語法之間進行選擇:sql 語法比 spark 語法更具可讀性,而且不那么冗長(對於數據庫用戶的角度)。從開發人員的角度來看,數據框語法可能更易讀。

使用“數據集”語法的主要優點是編譯器將能夠跟蹤一些錯誤。 使用任何字符串語法,如 sql 或列名 (col("mycol")) 將在運行時被發現。

如果小表中的數據小於閾值大小並且數據的物理文件是拼花格​​式,那么 spark 將自動廣播小表,但如果您從其他一些數據源(如 sql、PostgreSQL 等)讀取數據,則有時spark不會自動廣播表。

如果您知道表很小並且表的大小預計不會增加(在查找表的情況下),您可以顯式廣播數據框或表,這樣您就可以有效地將大表與小表連接起來.

您可以使用數據幀上的解釋命令驗證小表是否正在廣播,或者您也可以從 Spark UI 執行此操作。

正如答案中已經寫的那樣,廣播所有小表格的最佳方式。 而我們只能通過 SQL 來完成 - 提示:

val df = spark.sql("""
    select /*+ BROADCAST(t2, t3) */
        * 
    from bigtable t1
        left join small1 t2 using(id1) 
        left join small2 t3 using(id2)
""")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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