一、案例演示

1)没有使用map join


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

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

2) 使用map join 优化后


-- a 表是大表,数据量是百万级别
-- b 表是小表,数据量在百级别
-- 特别说明:mapjion括号中的b就是指定哪张表为小表
select /*+mapjoin(b)*/a.field1 as field1,b.field2 as field2,b.field3 as field3
from a left join bon 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 /*+mapjoin(small_table)*/big_table.a, small_table.b
from big_table left join small_tableon 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(tableNameA,tableNameB,...)*/ 才会执行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 垃圾回收机制【附原理图及调优方法】

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

Hive SQL 小表与大表Join 原理与实操相关推荐

  1. Hive中小表与大表关联(join)的性能分析

    经常看到一些Hive优化的建议中说当小表与大表做关联时,把小表写在前面,这样可以使Hive的关联速度更快,提到的原因都是说因为小表可以先放到内存中,然后大表的每条记录再去内存中检测,最终完成关联查询. ...

  2. oracle 表连接 大表小表_优化必备基础:Oracle中常见的三种表连接方式

    在Oracle SQL语句中,如果from后面有多个表时,表的连接方式是一个很重要的考量. 从Oracle 6开始,优化器就支持下面4种表连接方式: - 嵌套循环连接(Nested Loop Join ...

  3. NL连接一定是小表驱动大表效率高吗

    前言 两表使用nest loop(以下简称NL)方式进行连接,小表驱动大表效率高,这似乎是大家的共识,但事实上这是有条件的,并不总是成立.这主要看大表扫描关联字段索引后返回多少数据量,是否需要回表,如 ...

  4. Mysql之小表驱动大表

    Mysql之小表驱动大表 1 什么是小表驱动大表 2 为什么使用小表驱动大表 3 判断驱动表与非驱动表 4 Exists和in的使用场景 1 什么是小表驱动大表 用小的数据集去驱动(可理解为匹配)大的 ...

  5. MySQL IN、Exist关联查询时,我们为什么建议小表驱动大表?

    有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们要遵循一些原则,这样会使我们编写的SQL 语句在效率上快很多. 一.优化原则 小表驱动大表,即小的数据集驱动大 ...

  6. Mysql优化原则_小表驱动大表IN和EXISTS的合理利用

    //假设一个for循环 for($i = 0; $i < 10000; $i++) { for ($j = 0; $i < 50; $j++){} }for($i = 0; $i < ...

  7. MySql小表驱动大表

    有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们要遵循一些原则,这样会使我们编写的SQL 语句在效率上快很多. 一.优化原则 小表驱动大表,即小的数据集驱动大 ...

  8. mysql算法优化原则_Mysql优化原则_小表驱动大表IN和EXISTS的合理利用

    //假设一个for循环 for($i = 0; $i < 10000; $i++) { for ($j = 0; $i < 50; $j++) { } } for($i = 0; $i & ...

  9. MySQL关联查询时,我们为什么建议小表驱动大表?

    作者:留兰香丶 blog.csdn.net/codejas/article/details/78632883 有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们 ...

最新文章

  1. 别再写满屏的try-catch了,真丑,全局异常处理不会吗?
  2. WebForm与MVC混用
  3. Java软件开发:自定义MyBatis持久层框架
  4. python工资管理系统课程设计_Python3实现的简单工资管理系统示例
  5. 关于数组的 slice() 和 splice() 方法
  6. springmvc-实现增删改查
  7. [转]MFC子线程更改图像数据后更新主窗口图像显示方法
  8. 斯坦福大学CS143编译原理课程笔记:1.编译器与解释器简介
  9. tp3.2 缓存cache
  10. mysql bigint 转int_技术分享 | MySQL ?删库不跑路(建议收藏)
  11. wap绿色传奇搭建(纯净版)
  12. 《21天学通Java(第6版)》—— 1.7 问与答
  13. 禁忌搜索算法求解 TSP 问题的代码示例
  14. 截图工具FastStone Capture
  15. 51单片机流水灯和蜂鸣器同步
  16. 全国医院排名(2008)
  17. 基于python mediapipe的视频或者图片更换背景
  18. PHP自学---黑马程序员笔记【持续更新】
  19. 屏保:毛雷尔玫瑰屏保
  20. 时间“照妖镜”のmanic time

热门文章

  1. mac导出iphone手机上的ipa包
  2. mysql简化的审批流程表设计
  3. CF763D·Timofey and a flat tree
  4. python按条件统计excel分区数据
  5. h5+app如何打包,看这里就够了~
  6. 高速数据采集卡 1.25G ADC+12.6G DAC FMC子卡
  7. 基于人眼纵横比计算的人眼闭合检测算法
  8. 数据结构篇十七:图的最小生成树
  9. c语言实现的简单学生管理系统
  10. crack与split的区别_Split or Crack? Split 和 Crack 两词的区别(