我正在使用spark sql进行连接倍数表。其中一个表非常大,其他表很小(10-20个记录)。我真的想要使用包含键值对的其他表替换最大表中的值。
即。 Bigtable:
| 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)使用select方法广播表并进行连接。
spark.sql("
select *
from bigtable
left join small1 using(id1)
left join small2 using(id2)")
3)广播表和连接多个连接
bigtable.join(broadcast(small1), bigtable('col1') ==small1('col1')).join...
提前致谢
答案 0 :(得分:1)
您可以这样做:
spark.sql.autoBroadcastJoinThreshold
略微优于小表格行数来自动完成)运行一个加入大表的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”))将在运行时被发现。
答案 1 :(得分:0)
如果你的小表中的数据小于阈值大小并且你的数据的物理文件是拼花格式,那么spark会自动广播小表,但如果你从其他一些数据源读取数据,比如sql、PostgreSQL等等,然后有时spark不会自动广播表。
如果您知道表很小并且表的大小预计不会增加(在查找表的情况下),您可以显式广播数据框或表,这样您就可以有效地加入更大的表小桌子。
您可以使用数据帧上的解释命令验证小表是否正在广播,或者您也可以从 Spark UI 执行此操作。