【大数据之Hive】二十一、HQL语法优化之分组聚合优化

news/2024/8/19 14:23:41

1 优化说明

  在Hive中没有优化过的分组聚合:通过MR任务实现。Map端负责读数据,按分区字段分区,通过Shuffle,将数据发往Reduce端,各组数据在Reduce端完成最终的聚合运算。
  Hive分组聚合优化主要针对减少Shuffle的数据量,使用map-site聚合,在map端维护一个hash table,对数据进行聚合,聚合结果按分组字段分区发送到reduce端。

map-side 聚合相关参数:

--启用map-side聚合,默认为true
set hive.map.aggr=true;

--用于检测源表数据是否适合进行map-side聚合。检测的方法是:
--先对若干条数据进行map-side聚合,
--若聚合后的条数和聚合前的条数比值小于该值,则认为该表适合进行map-side聚合;
--否则,认为该表数据不适合进行map-side聚合,后续数据便不再进行map-side聚合。
set hive.map.aggr.hash.min.reduction=0.5;

--用于检测源表是否适合map-side聚合的条数。
set hive.groupby.mapaggr.checkinterval=100000;

--map-side聚合所用的hash table,占用map task堆内存的最大比例,
--若超出该值,则会对hash table进行一次flush。
sethive.map.aggr.hash.force.flush.memory.threshold=0.9;

2 优化案例

优化前
先设置map-site聚合为关闭状态,再执行SQL:

set hive.map.aggr=false;

select
    product_id,
    count(*)
from  order_detail
group by product_id;

  未经过优化的分组聚合执行计划如下:
  stage1:先扫描order_detail表->select product_id的字段->数据读入之后直接写入ruduce,没有经过map->在reduce端直接group by聚合->将数据发送到HDFS中。
在这里插入图片描述
在Yarn监控页面可以看到执行的时间。

优化
设置参数为true,再执行SQL。

set hive.map.aggr=true;

select
    product_id,
    count(*)
from  order_detail
group by product_id;

优化后
执行计划:
  stage1:先扫描order_detail表->select product_id的字段->使用hash table进行分组集合->数据读入之后直接写入ruduce,没有经过map->在reduce端对每一个Mapper发送来的数据进行group by合并->将数据发送到HDFS中。
在这里插入图片描述
  查看执行时间,发现优化之后效果不明显。

原因:
  可能在Map端进行分组聚合没有执行到需要的结果,检测表数据时可能不适合进行map-site聚合。

方法:
  查看yarn中map的日志syslog,可以看到Map-Reduce的统计信息,Map的输入输出数据并没有发生大变化,可以说明在Map底层中,分组聚合并没有达到想要的效果,即在检验数据时认为该数据不适合做分组聚合。

Hive认为不适合做分组聚合的原因:
  原表有2000W条数据,聚合到100W条,即聚合后的条数比聚合前的条数比值为1/20<0.5,按理说是可以做map-site聚合的。因为HIVE在校验时只对切片的表的开头的一段数据进行判断,当开头的一段数据校验后显示唯一的就不再对该切片的数据进行聚合。

强制实行分组聚合的方法:
  因为比值为比值为1/20<0.5,实际上该数据是适合做分组聚合的。
  将检测表数据的参数调整为1,再重新执行SQL。

set hive.map.aggr.hash.min.reduction=1;

  查看yarn的Map端执行日志,观察数据量的变化,输出数据有明显减少。但聚合后Map端输出的行数是大于100W的。

原因:
  当hash table占用map task堆内存已经超过最大比例,触发了Flush。在Flush前已经有某些ID的数据了,该数据已经输出了,flush之后还会重新进行hash计算,还有可能出现一些ID为已经输出的数据。也即一个ID的数据可能会输出多遍。

发生Flush的次数多了,聚合效果就不太好,继续优化方法:
  把flush的阈值调大些,如果效果还是不明显则说明总内存小,可以调大总内存。

--map-side聚合所用的hash table,占用map task堆内存的最大比例,
--若超出该值,则会对hash table进行一次flush。
sethive.map.aggr.hash.force.flush.memory.threshold=0.9;

--进一步优化
set  mapreduce.map.memory.mb=2048;

http://lihuaxi.xjx100.cn/news/1334480.html

相关文章

vue语法详解

模板语法 注意 模板语法不能在标签属性中用 文本插值 {{ msg }} 使用JavaScript表达式 {{ number 1 }} {{ ok ? YES : NO }} {{ message.split().reverse().join() }} 使用HTML 双大括号将会将数据插值为纯文本&#xff0c;而不是HTML&#xff0c;若想插入 HTML&…

Android车载需要学习哪些知识?

要进行Android车载开发&#xff0c;您需要学习以下知识&#xff1a; Android开发基础&#xff1a;了解Android操作系统的架构、应用组件、布局和UI设计等基本概念&#xff0c;掌握Java或Kotlin编程语言。 车载系统架构&#xff1a;熟悉车载系统的架构和组成部分&#xff0c;了…

谷歌插件下载Redux DevTools管理Redux数据

我们在做 react-redux开发时 很多时候可能无法确定自己的数据有没有成功导进来 这里就有个不错的谷歌插件推荐给大家 大家可以下载我的资源 谷歌插件Redux DevTools 这里 我们打开 Google Chrome浏览器 然后 直接在谷歌浏览器上访问 chrome://extensions/ 如果你的第一次进入 …

玩转CSS基础:CSS选择器

记录不常用&#xff0c;一知半解&#xff0c;或者不了解的知识点&#xff0c;及时查漏补缺&#xff0c;提高技术水平。 CSS选择器 标签属性选择器 <a title"我是超链接" href"www">点击我</a>根据一个元素上的某个标签的属性的存在以选择元素…

力扣 | 二分查找模板

力扣&#xff1a;二分查找 文章目录 &#x1f4da;二分查找&#x1f4da;模板I&#x1f449;x 的平方根&#x1f449;猜数字大小&#x1f449;搜索旋转排序数组 &#x1f4da;模板II&#x1f449;第一个错误的版本&#x1f449;寻找峰值 &#x1f4da;模板III&#x1f449;在排…

Python ARP缓存投毒(ARP欺骗)

原理介绍 https://mohen.blog.csdn.net/article/details/100576912 投毒技术 ARP投毒的逻辑:欺骗目标设备,使其相信我们是它的网关;然后欺骗网关,告诉它要发给目标设备的所有流量必须交给我们转发。网络上的每一台设备,都维护着一段ARP缓存,里面记录着最近一段时间本地…

「JVS低代码开发平台」多账号统一登录功能介绍

JVS基础框架的定位是企业级的统一信息化的数字底座&#xff0c;统一登录时JVS基础框架最基础的能力&#xff0c;下面我们先看下登录的演示操作&#xff1a; JVS统一登录功能介绍 功能需求说明 功能需求来源于企业的日常工作过程中&#xff0c;有太多的账号与密码需要记录&…

比较器,迟滞比较器

自记&#xff1a; 一、什么是比较器&#xff1f; 比较器&#xff0c;具有两个模拟电压输入端UIN和UIN-&#xff0c;一个数字状态输出端UOUT&#xff0c;输出端只有两种状态&#xff0c;用以表示两个输入端电位的高低关系&#xff1a; UH代表高电平&#xff0c;UL代表低电平&a…