Hive SQL 小表与大表Join 原理与实 ***

Hive SQL 小表与大表Join 原理与实 *** ,第1张

Hive SQL 小表与大表Join 原理与实 *** 一、案例演示

1)没有使用map join 

-- a 表是大表,数据量是百万级别
-- b 表是小表,数据量在百级别
select 
	a.field1 as field1,
	b.field2 as field2,
	b.field3 as field3
from a left join b
	on a.field1 = b.field1;

运行时间为:总耗时:08:10:03

2) 使用map join 优化后

-- a 表是大表,数据量是百万级别
-- b 表是小表,数据量在百级别
-- 特别说明:mapjion括号中的b就是指定哪张表为小表
select 
	 
	a.field1 as field1,
	b.field2 as field2,
	b.field3 as field3
from a left join b
	on a.field1 = b.field1;

 运行时间为:总耗时:00:12:39

通过对比,map join大大提升了SQL执行效率,节省分析时间


 二、map join是如何解决数据小表与大表join优化?

背景说明:A表有百万级、千万级、亿级,B表2万行及2万以内的记录,而且A表中数据倾斜特别严重,有一个key上有30%或40%以上记录,在运行中特别的慢,而且在reduce的过程中遇到内存不够而报错。

这个问题属于典型的小表与join优化问题,考虑使用mapjoin 进行优化

mapjoin的原理: MapJoin 会把小表全部读入内存中,在map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在map是进行了join *** 作,省去了reduce 阶段,运行的效率就会高很多。

为了更方便理解,mapjoin原理大白话:小表复制到各个节点上,并加载到内存中;大表分片,与小表完成连接 *** 作。

这样就不会由于数据倾斜导致某个reduce上落的数据太多而失败。于是原来的sql 可以通过使用hint 的方式指定join 时使用 mapjoin,示例如下:

select 
	
	big_table.a, small_table.b
from big_table left join small_table
	on big_table.a = small_table.a;

 添加了hint 显示明确将small_table 读入内存中,通过此方式运行的话效率比以前的写法高了很多。

那么问题来了,什么样的表应该被视为小表small_table?

       参与连接的小表的行数,以不超过2万条为宜,大小不超过25M.


 三、map join原理

Hive 整个过程分为Map、Shuffle、Reduce三大阶段。

简单的说,Hive中的Join 可分为Common Join(Reduce阶段完成join)和 Map Join (Map阶段完成join)。

A、Map阶段

       读取源表的数据,Map输出时候以Join on条件中的列为key,如果Join有多个关联键,则以这些关联键的组合作为key;Map输出的value 为join之后所关心的(select 或者where 中需要用到的)列;同时在value中还会包含表的Tag信息,用于标明此value对应哪个表;按照key进行排序

B、Shuffle阶段

       根据key的值进行hash,并将key/value按照hash值推送至不同的reduce中,这样确保两个表中相同的key位于同一个reduce中

C、Reduce阶段

        根据key的值完成join *** 作,期间通过Tag来识别不同表中的数据。


1)Hive Common Join

如果不指定Map Join或者不符合MapJoin的条件,那么Hive解析器会将Join *** 作转换成Common Join,即:在Reduce阶段完成join. 即:需要通过map、shuffle、reduce三个大的阶段


 2)Hive Map Join

2.1 什么是Map Join?

        MapJoin 顾名思义,就是在Map阶段进行表之间的连接。而不需要进入到Reduce阶段才进行连接。这样就节省了在Shuffle阶段时要进行的大量数据传输。从而起到了优化作业的作用。

2.2 MapJoin的原理:

       通过情况下,要连接的各个表里面的数据会分布在不同的Map中进行处理。即同一个Key对应的Value可能存在不同的Map中。这样就必段等到Reduce中去连接。要使MapJoin能够顺利进行,那就必段满足这样的条件:除了一份表的数据分布在不同的Map中外,其他连接的表的数据必须在每个Map中有完整的拷贝。

2.3 MapJoin适用的场景:

       通过上面分析你会发现,并不是所有的场景都适合用MapJoin。它通常会用在如下的一些情景:在二个要连接的表中,有一个很大,有一个很小,这个小表可以存放在内存中而不影响性能。这样我们就把小表文件复制到每一个Map任务的本地,再让Map把文件读取内存中待用。

2.4 MapJoin的实现方法:

       1)在Map-Reduce的驱动程序中使用静态方法,DistributedCache.addCacheFile() 增加要拷贝的小表文件。JobTracker在作业启动之前会获取这个URI列表,并将相应的文件拷贝到各个TaskTracker的本地磁盘上。

        2)在Map类的setup方法中使用DistributedCache.getLocalCacheFiles() 方法获取文件目录,并使用标准的文件读写API读取相应的文件。

2.5 Hive 内置提供的优化机制之一就包括MapJoin

        A、在Hive v0.7之前,需要使用hint 提示 才会执行MapJoin。

        B、Hive v0.7之后的版本已经不需要给出MapJoin的指示就进行优化。它是通过如下配置参数来控制的:

hive> set hive.auto.convert.join=true;

Hive 还提供另外一个参数,就是:表文件的大小作为开启和关闭MapJoin的阈值。

hive> set hive.mapjoin.smalltable.filesize=25000000 即25M


 文章最后,给大家推荐一些受欢迎的技术博客链接

  1. JAVA相关的深度技术博客链接
  2. Flink 相关技术博客链接
  3. Spark 核心技术链接
  4. 设计模式 —— 深度技术博客链接
  5. 机器学习 —— 深度技术博客链接
  6. Hadoop相关技术博客链接
  7. 超全干货--Flink思维导图,花了3周左右编写、校对
  8. 深入JAVA 的JVM核心原理解决线上各种故障【附案例】
  9. 请谈谈你对volatile的理解?--最近小李子与面试官的一场“硬核较量”
  10. 聊聊RPC通信,经常被问到的一道面试题。源码+笔记,包懂
  11. 深入聊聊Java 垃圾回收机制【附原理图及调优方法】

欢迎扫描下方的二维码或 搜索 公众号“大数据高级架构师”,我们会有更多、且及时的资料推送给您,欢迎多多交流!

                                           

       

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5636478.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存