繁体   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