Hive优化补充

news2025/1/18 18:52:24

目录

一、表设计优化

1.通过设计分区表,增加动态分区,查询时避免全表扫描

2.设计分桶表:适用于大表join大表的情况

最后,两张大表进行join转为两张分桶表进行join:

二、文件存储

1.文件格式-概述

2.文件格式——TextFile

3.文件格式——SequenceFile

4.文件格式——Parquet

5.文件格式——ORC

三、数据压缩

1.数据压缩概述

2.Hive中压缩

3.Hive中压缩配置

四、存储优化

1.避免小文件生成

2.合并小文件——当读取的数据就是小文件时

​编辑3.ORC文件索引  ​编辑

4.ORC矢量化查询——按批读取

五、Explain执行计划 

六、MR属性优化

1.本地模式

2.并行执行

七、Job优化

1.Map Join——小表join大表

2.reduceJoin——大表join大表

3.Bucket Join——大表Join大表

八、优化器——关联优化

九、CBO优化

1.优化器引擎——背景

2.优化器引擎——CBO优化器

十、谓词下推(PPD)

十一、数据倾斜

(一)group by倾斜优化

1.开启Map端聚合

2.实现随机分区

3.数据倾斜时自动负载均衡——空间换时间

(二)join倾斜优化

1.提前过滤,将大数据变成小数据,实现Map Join

2.使用Bucket Join

3.使用Skew Join


本篇文章是对我之前写的《Hive学习——企业级调优》的补充。


一、表设计优化

1.通过设计分区表,增加动态分区,查询时避免全表扫描

2.设计分桶表:适用于大表join大表的情况

当10万条数据的用户表join 1000万条数据的订单表时,通过设置分桶表,每个用户装在一个桶中,避免了全表扫描。这样的 join 称为 SMB map join (Sort Merge Bucket Map Join),核心思想是大表化成小表,分而治之。

-- 第一张普通表
select *
from dw_zipper;

dw_zipper.userid	dw_zipper.phone	dw_zipper.nick	dw_zipper.gender	dw_zipper.addr	dw_zipper.starttime	dw_zipper.endtime
001	186xxxx1234	laoda	NULL	sh	2021-01-01	9999-12-31
002	186xxxx1235	laoer	1	bj	2021-01-01	9999-12-31
003	186xxxx1236	laosan	0	sz	2021-01-01	9999-12-31
004	186xxxx1237	laosi	1	gz	2021-01-01	9999-12-31
005	186xxxx1238	laowu	0	sh	2021-01-01	9999-12-31
006	186xxxx1239	laoliu	1	bj	2021-01-01	9999-12-31
007	186xxxx1240	laoqi	0	sz	2021-01-01	9999-12-31
008	186xxxx1241	laoba	1	gz	2001-01-01	9999-12-31
009	186xxxx1241	laojiu	0	sh	2021-01-01	9999-12-31
010	186xxxx1234	laoshi	1	bj	2021-01-01	9999-12-31

-- 另一张大表
select *
from ods_zipper_update;

ods_zipper_update.userid	ods_zipper_update.phone	ods_zipper_update.nick	ods_zipper_update.gender	ods_zipper_update.addr	ods_zipper_update.startitme	ods_zipper_update.endtime
008	186xxxx1241	laoda	1	sh	2021-01-02	9999-12-31
011	186xxxx1244	laoshi	1	jx	2021-01-01	9999-12-31
012	186xxxx1245	laoshi	0	zj	2021-01-01	9999-12-31

explain
select a.userid,
       a.phone
from dw_zipper a
         join ods_zipper_update b on a.userid = b.userid;

设置参数之前,普通join相连:

设置参数之后:将两张大表分别insert到两个分桶表中,分桶字段就是等值连接的字段

-- todo 第一张分桶表
create table tb01
(
    userid    string,
    phone     string,
    nick      string,
    gender    int,
    addr      string,
    startitme string,
    endtime   string
) clustered by (userid) sorted by (userid asc) into 3 buckets
    row format delimited fields terminated by '\t';

-- todo 第二张分桶表
create table tb02
(
    userid    string,
    phone     string,
    nick      string,
    gender    int,
    addr      string,
    startitme string,
    endtime   string
) clustered by (userid) sorted by (userid asc) into 3 buckets
    row format delimited fields terminated by '\t';

-- todo 第一张分桶表赋值
insert into tb01 select * from dw_zipper;

select * from tb01;

-- todo 第二张分桶表赋值
insert into tb02 select * from ods_zipper_update;

select * from tb02;

分桶后要设置下面三个参数:

set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;

最后,两张大表进行join转为两张分桶表进行join:

explain
select tb01.*
from tb01
         join tb02 on tb01.userid = tb02.userid;

执行计划变为bucket-mapJoin

二、文件存储

1.文件格式-概述

  • Hive数据存储的本质还是HDFS,所有的数据读写都基于HDFS的文件来实现;

  • 为了提高对HDFS文件读写的性能,Hive提供了多种文件存储格式:TextFile、SequenceFile、ORC、Parquet等;

  • 不同的文件存储格式具有不同的存储特点,有的可以降低存储空间,有的可以提高查询性能。  

  • Hive的文件格式在建表时指定,默认是TextFile,建表时storted as 后面可以指定文件格式,该条语句不写,默认是TextFile:

2.文件格式——TextFile

  • TextFile是Hive中默认的文件格式,存储形式为按行存储。
  • 工作中最常见的数据格式就是TextFile文件,几乎多有的原始数据生成都是TextFile格式,所以Hive设计时考虑到了避免各种编码及数据错乱的问题,选用了TextFile作为默认的格式。
  • 建表时不指定存储格式即为TextFile,导入数据时把数据文件拷贝到HDFS不进行处理。

案例:

 

文件大小不变:

3.文件格式——SequenceFile

  • SequenceFile是Hadoop里用来存储序列化的键值对,即二进制的一种文件格式。
  • SequenceFile文件也可以作为MapReduce作业的输入和输出,Hive也支持这种格式。

案例:
注意:指定存储格式时,直接将要存储的文件load到表中,数据并不能变为指定格式,必须要insert+select语法,底层走MR,才能将文件变为指定格式进行存储。

create table tb_sogou_seq()
row format delimited fields terminated by '\t'
stored as sequencefile;

insert into table tb_sogou_seq
select * from tb_sogou_source;

文件变小:

但是下载后是二进制文件:

4.文件格式——Parquet

  • Parquet是一种支持嵌套结构的列式存储文件格式
  • 是一种支持嵌套数据模型对的列式存储系统,作为大数据系统中OLAP查询的优化方案,它已经被多种查询引擎原生支持,并且部分高性能引擎将其作为默认的文件存储格式。
  • 通过数据编码和压缩,以及映射下推和谓词下推功能,Parquet的性能也较之其它文件格式有所提升。

案例:

create table tb_sogou_parquet()
row format delimited fields terminated by '\t'
stored as parquet;

insert into table tb_sogou_parquet
select * from tb_sogou_source;

文件变小:

5.文件格式——ORC

  • ORC文件格式也是一种Hadoop生态圈中的列式存储格式;
  • 它用于降低Hadoop数据存储空间和加速Hive查询速度;

 案例:

create table tb_sogou_orc()
row format delimited fields terminated by '\t'
stored as orc;

insert into table tb_sogou_orc
select * from tb_sogou_orc;

ORC文件格式将文件压缩地很小:

但是ORC底层为了降低存储空间,采用二进制序列化存储


总结:Hive推荐使用列式存储格式。

三、数据压缩

1.数据压缩概述

2.Hive中压缩

3.Hive中压缩配置


总结:实际工作中文件的压缩格式需要综合来选择。

四、存储优化

1.避免小文件生成

2.合并小文件——当读取的数据就是小文件时

3.ORC文件索引 

Bloom过滤器:当它说一个值不存在时,一定不存在;当它说一个值存在时,可能存在。

4.ORC矢量化查询——按批读取

五、Explain执行计划 

 

六、MR属性优化

1.本地模式

set hive.exec.mode.local.auto=true;

注意:(1)当文件大小<128MB;

           (2)mapTasks<4 

           (3)reduceTasks=1 or reduceTasks=0;

满足上面三个中的任意一个就能自动转换为本地模式,默认是false关闭状态。

2.并行执行

七、Job优化

hive可以自动判断用map端还是reduce端进行join。

1.Map Join——小表join大表

在Map端进行join没有reduce,无需shuffle;

MapTask可以根据数据量大小自动调整并发度;

将小表数据做为分布式缓存,发送到各台机器上,再启动一个或多个MapTask读取大表数据,分别与缓存之间进行关联,关联结果输出。

2.reduceJoin——大表join大表

        分别读取两份大表的数据,在shuffle过程中,根据字段相同分到同一个reduce,将数据放在一起,在reduce阶段完成join操作。

3.Bucket Join——大表Join大表

如果桶表join中,join的字段不是分桶的字段,将没有任何意义。

(1)桶表join优化

 

(2)SMB——除了桶表的join优化,还有桶表排序的join优化

八、优化器——关联优化

如果某些操作有相关性,可以放在一个MR中实现,例如上面的group by和order by的字段都是相同字段。

九、CBO优化

1.优化器引擎——背景

2.优化器引擎——CBO优化器

那么CBO引擎是如何判断哪种查询方案是更高效呢?原因是它的底层是Analyze分析器。

十、谓词下推(PPD)

十一、数据倾斜

(一)group by倾斜优化

MR再运行HQL语句时,将相同的key分到一组,某一组的key有时会很多,另外一组的key很少,这就出现了数据倾斜。

1.开启Map端聚合

set hive.map.aggr=true;

通过减少shuffle数据量和Reducer阶段的执行时间,避免每个YTask数据差异过大导致数据倾斜。

2.实现随机分区

selcet * from table distribute by rand();

distribute by 用于指定底层按照哪个字段作为key实现分区、分组等,通过rank函数随机值实现随机分区,避免数据倾斜。

3.数据倾斜时自动负载均衡——空间换时间

set hive.groupby.skewindata=true

开启该参数以后,当前程序会自动通过两个MapReduce来运行。

第一个MR自动进行随机分布到Reducer中,每个Reducer做部分聚合操作,输出结果。

第二个MR将上一步聚合的结果再按照业务(group by key)进行处理,保证相同的分布到一起,最终聚合得到结果。

总之就是:先将key打散,分到不同的reducer中,然后再进行聚合。

(二)join倾斜优化

1.提前过滤,将大数据变成小数据,实现Map Join

2.使用Bucket Join

        如果使用方案1,过滤后的数据依旧是一张大表,那么最后的Join依旧是一个Reduce Join,这种场景下,可以将两张表的数据构建为桶表,实现Bucket Map Join,避免数据倾斜。

3.使用Skew Join

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/470348.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学系统集成项目管理工程师(中项)系列13b_人力资源管理(下)

1. 项目团队建设 1.1. 塔克曼(Tuckman)阶梯理论 1.2. 理论基础 1.2.1. 激励理论 1.2.1.1. 马斯洛需要层次理论 1.2.1.1.1. 生理需要 1.2.1.1.2. 安全需要 1.2.1.1.3. 社会交往的需要 1.2.1.1.4. 自尊的需要 1.2.1.1.5. 自我实现的需要 1.2.1.2. 赫茨伯格的双因素理论…

Leetcode力扣秋招刷题路-0802

从0开始的秋招刷题路&#xff0c;记录下所刷每道题的题解&#xff0c;帮助自己回顾总结 802. 找到最终的安全状态 有一个有 n 个节点的有向图&#xff0c;节点按 0 到 n - 1 编号。图由一个 索引从 0 开始 的 2D 整数数组 graph表示&#xff0c; graph[i]是与节点 i 相邻的节…

Git HEAD及detached head

背景&#xff1a;最近在使用git checkout重置HEAD指向&#xff0c;偶尔会出现Detached HEAD提示&#xff0c;于是想探究一下具体的原理及过程&#xff0c;遂写下了这篇文章。一般checkout用于切换分支和检出历史的某个节点&#xff0c;或恢复工作区的文件&#xff0c;这三个功能…

OpenHarmony JS Demo开发讲解

项目结构 打开entry→src→main→js&#xff0c;工程的开发目录如图所示 其中&#xff0c; i18n文件夹&#xff1a;用于存放配置不同语言场景的资源&#xff0c;比如应用文本词条&#xff0c;图片路径等资源。en-US.json文件定义了在英文模式下页面显示的变量内容&#xff0c…

Java 泛型为什么设计成是可以擦除的

Java 泛型是 Java 5 引入的一种类型安全的编程机制&#xff0c;它允许在编译时指定泛型类型参数&#xff0c;从而提高代码的类型安全性和可读性。然而&#xff0c;Java 泛型的实现方式是通过类型擦除来实现的&#xff0c;这也引发了一些争议。本文将介绍 Java 泛型为什么设计成…

2023年某科技公司前端开发初级岗的面试笔试真题(含选择题答案、问答题解析、机试题源码)

📚关于该专栏: 该专栏的发布内容是前端面试中笔试部分真题、答卷类、机试等等的题目,题目类型包括逻辑题、算法题、选择题、问答题等等,除了内容的分享,还有解析和答案。真实来自某些互联网公司,坐标广东广州。 🔥🔥🔥 持 续 更 新 🔥🔥🔥 😉专栏博主: 黛…

HCIP-7.1交换机ARP、VLAN之间的三层通信技术学习

交换机ARP、VLAN之间的三层通信技术学习 1、ARP1.1、 地址解析过程1.2、ARP报文格式1.3、ARP表项1.4、免费ARP1.5、 VLAN间ARP代理1.5.1、解决同网段&#xff0c;不同广播域内主机互通问题&#xff1b;1.5.2、解决同网段&#xff0c;不同VLAN之间主机互通问题。1.5.3、解决同网…

Ignore insecure directories and continue [y] or abort compinit [n]?

问题&#xff1a; 在Mac终端中使用Zsh作为默认shell时&#xff0c;有时会弹出以下提示信息&#xff1a; Ignore insecure directories and continue [y] or abort compinit [n]? 这个提示出现的原因是因为Zsh在加载时会检查所有的目录是否安全&#xff0c;并拒绝加载不安全的…

【LeetCode: 62. 不同路径 | 暴力递归=>记忆化搜索=>动态规划 】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

卡尔曼滤波器简介——概述

关于卡尔曼滤波器 大多数现代系统都有许多传感器&#xff0c;可以根据一系列测量来估计隐藏&#xff08;未知&#xff09;状态。例如&#xff0c;GPS接收器提供位置和速度估计&#xff0c;其中位置和速度是隐藏状态&#xff0c;卫星信号到达的差分时间是测量值。 跟踪和控制系统…

ChatGPT的进化版?AutoGPT怎么用

AutoGPT是什么 首选给大家介绍&#xff0c;ChatGPT与AutoGPT的区别 目前AutoGPT被称为最接近AGI的人工智能&#xff0c;它是ChatGPT的进化版&#xff1f; “ChatGPT” 只能提供2021年9月之前的信息&#xff0c;所以你问它告诉我今天的天气&#xff0c;它回答不了 “AutoGPT” …

AutoGPT不靠谱,微软推出升级版!可编辑自主规划过程

夕小瑶科技说 原创 作者 | iven 火遍全网的AutoGPT[1]在Github收藏量突破十万。这种自我规划、自我执行的智能体首次关注人工智能模型内部的自我调整与优化。 但是有不少网友发现&#xff0c;AutoGPT的表现不稳定&#xff0c;死循环是最常见的现象。此外&#xff0c;AutoGPT执…

输入指令为±10V或4~20mA型伺服阀控制器

工作电压 19~35 VDC&#xff08;常规24VDC&#xff09; 最大功率消耗 &#xff1c;25VA 空载电流 ≤100mA&#xff08;24V&#xff09; 差分信号输入 0~10 V&#xff0c;输入阻抗≥100KΩ 4~20 mA&#xff0c;输入阻抗100Ω &#xff08;出厂前需指定&#xff0c;现场不可…

免费的ERP系统哪个好?这款让管理更高效

阅读本文你将了解&#xff1a;ERP是什么&#xff1f;解决什么问题&#xff1f;ERP选型的参考维度&#xff1f;零代码ERP系统解决哪些场景问题&#xff1f; 题目提到“免费”&#xff0c;其实很难有软件可以真正做到。 商业化市场决定了没有一家厂商可以不落俗套。因而我们要探…

[架构之路-177]-《软考-系统分析师》-17-嵌入式系统分析与设计 -2- 系统分析与设计、低功耗设计

目录 1 7 . 4 嵌 入 式 系 统 开 发 17.4.1 开发平台 1 . 交叉开发环境 2 . 交叉编译环境 17. 2 开发流程 1. 过程模型 2 . 分析与设计方法 17.4.3 软硬件协同设计 1 . 软 硬 件 协 同 设 计 方 法 2 . 协 同 设 计 工 具 17.4.4 系统分析与设计 1 . 需求分析 2 .…

CI/CD: GitLab Runner安装注册配置管理

点击上方蓝字⭐️关注“DevOps云学堂”&#xff0c;接收最新技术实践 今天是「DevOps云学堂」与你共同进步的第 21 天 本文是《GitLabCI实践》教程部分内容 GitLab Runner是一个开源项目&#xff0c;用于运行您的作业并将结果发送回GitLab。它与GitLab CI结合使用&#xff0c;G…

计算机网络学习10(ARP协议详解)

ARP 协议&#xff0c;可以说是在协议栈中属于一个偏底层的、非常重要的、又非常简单的通信协议。 开始阅读这篇文章之前&#xff0c;你可以先看看下面几个问题&#xff1a; ARP 协议在协议栈中的位置&#xff1f; ARP 协议在协议栈中的位置非常重要&#xff0c;在理解了它的工…

Linux 内存 pt.1

哈喽大家好&#xff0c;我是咸鱼 今天我们来学习一下 Linux 操作系统核心之一&#xff1a;内存 跟 CPU 一样&#xff0c;内存也是操作系统最核心的功能之一&#xff0c;内存主要用来存储系统和程序的指令、数据、缓存等 关于内存的学习&#xff0c;我会尽量以通俗易懂的方式…

R语言的基本数学运算

目录 一、对象命名原则 二、基本数学运算 2.1 四则运算 2.2 余数和整除 2.3 次方或平方根 2.4 绝对值 2.5 exp()与对数 2.6 科学符号e 2.7 圆周率与三角函数 2.8 四舍五入函数 2.9 近似函数 2.10 阶乘 三、R语言控制运算的优先级 四、无限大 五、非数字&#xf…

OpenCV 实战3 对图像画框、获取图像像素位置

一、函数介绍 opencv中进行鼠标操作主要用到setMouseCallback这个函数&#xff0c;如下&#xff1a; void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata 0); winname&#xff1a;窗口名称 onMouse&#xff1a;鼠标响应函数&#x…