hive中2种常用的join方式
在最近的项目代码review中,发现之前代码小表关联大表的业务,小表经过过滤后,数据只有400多条,而大表有1600万条,之前的逻辑是使用的是小表 join 大表,运行时间1小时12分钟;经过优化后,使用了map join的方式,将小表放到内存中,运行时间7分钟。
借此机会回顾下hive中2种常用的join方式:Map Join、Reduce Join(也叫Common Join)
应对场景:
-
Map Join:适用于小表关联大表
-
Reduce Join:适用于大表关联大表
Map Join
Map Join通常用于一个很小的表和一个很大的表关联,将小表放入内存中,具体小表有多小,由参数hive.mapjoin.smalltable.filesize来决定,默认值为 25M,满足条件的Hive在执行时会自动转化为Map Join,或者使用
/*+ mapjoin(table) */
执行 MapJoin
从上图中,我们可以看到小表b转成成一个HashTable的数据结构,并写入本地文件,之后加载到了distribute cache中,然后下面的task b就不需要reduce,直接输出结果。
示例:
select /*+ MAPJOIN(time_dim) */ count(1) from
store_sales join time_dim on (ss_sold_time_sk = t_time_sk)
Reduce Join
Reduce Join分为三个阶段,即map阶段,shuffle阶段,reduce阶段
-
map阶段:
读取表,将原始数据解析成hive内部的数据结构;执行查询中可在map阶段执行的操作,如where条件,select、简单的表达式计算,这些操作成为map-side操作,可减少传递给shuffle阶段的数据量,提高查询效率等;生成键值对,方便后续shuffle阶段根据key进行分组和排序。 -
shuffle阶段:
负责将map阶段的数据分区(partitioning)、排序(sorting)、分组(grouping),确保相同key的数据被发送到同一个Reduce任务进行处理。确保数据在map和reduce之间的正确分配和有序传递,是整个查询执行过程中最复杂且资源消耗最大的阶段
reduce阶段: -
reduce阶段
负责接收shuffle阶段的数据,将数据聚合、汇总和最终结果生成。从shuffle阶段接收具有相同Key的键值对集合,然后对Value聚合,最后写入HDFS。
SMB Join
-
Sort Merge Bucket Map Join(SMB Join) 适用于大表与大表之间的 Join,但前提是表已经按照 Join Key 进行了排序和分桶。
-
原理:利用预处理(排序+分桶)的特性,在 Map 阶段直接完成 Join,避免 Shuffle 和 Reduce 开销,大幅提升查询性能。
-
适用场景:数据仓库中的大表关联查询,尤其是已经预处理(排序+分桶)的表。
参考连接:
https://www.cnblogs.com/raymoc/p/5323824.html
https://blog.csdn.net/weixin_44320890/article/details/114702855