kaiyun.com 口试 | 不成不知的十大 Hive 调优手段优秀推行

发布日期:2023-12-09 13:22    点击次数:189


[[442967]]

Apache Hive是建设在Apache Hadoop之上的数据仓库软件形状,用于提供数据查询和分析。Hive是Hadoop在HDFS上的SQL接口,它提供了访佛于SQL的接口来查询存储在与Hadoop集成的多样数据库和文献系统中的数据。不错说从事数据开采责任,不论是在平时的责任中,也曾在口试中,Hive具有举足轻重的地位,尤其是Hive的性能调优方面,不仅大致在责任中进步恶果而且还不错在口试中脱颖而出。在本文中,我将共享十个性能优化手艺,全文如下。

1.屡次INSERT单次扫描表

默许情况下,Hive会推行屡次表扫描。因此,如若要在某张hive表中推行多个操作,提议使用一次扫描并使用该扫描来推行多个操作。

比如将一张表的数据屡次查询出来装载到另外一张表中。如底下的示例,表my_table是一个分区表,分区字段为dt,如若需要在表中查询2个特定的分区日历数据,并将记载装载到2个不同的表中。

INSERT kaiyun.comINTO temp_table_20201115 SELECT * FROM my_table WHERE dt ='2020-11-15'; INSERT INTO temp_table_20201116 SELECT * FROM my_table WHERE dt ='2020-11-16'; 

在以上查询中,Hive将扫描表2次,为了幸免这种情况,咱们不错使用底下的形状:

FROM my_table INSERT INTO temp_table_20201115 SELECT * WHERE dt ='2020-11-15' INSERT INTO temp_table_20201116 SELECT * WHERE dt ='2020-11-16' 

这么不错确保只对my_table表推行一次扫描,从而不错大大减少推行的时刻和资源。

2.分区表

对于一张比拟大的表,将其联想身分区表不错进步查询的性能,对于一个特定分区的查询,只会加载对应分区旅途的文献数据,因此,当用户使用特定分区列值推行遴荐查询时,将仅针对该特定分区推行查询,由于将针对较少的数据量进行扫描,是以不错提供更好的性能。值得提防的是,分区字段的遴荐是影响查询性能的进击因素,尽量幸免层级较深的分区,这么会形成太多的子文献夹。

目下问题来了,该使用哪些列进行分区呢?一条基本的法例是:遴荐低基数属性四肢“分区键”,比如“地区”或“日历”等。

一些常见的分区字段不错是:

日历或者时刻

比如year、month、day或者hour,当表中存在时刻或者日历字段时,不错使用些字段。

地舆位置

比如国度、省份、城市等

业务逻辑

比如部门、销售区域、客户等等

CREATE TABLE table_name (     col1 data_type,     col2 data_type) PARTITIONED BY (partition1 data_type, partition2 data_type,….); 
3.分桶表

等闲,当很难在列上创建分区时,咱们会使用分桶,比如某个时时被筛选的字段,如若将其四肢分区字段,会形成巨额的分区。在Hive中,会对分桶字段进行哈希,从而提供了中罕见的数据结构,进行进步查询恶果。

与分区表访佛,分桶表的组织形状是将HDFS上的文献分割成多个文献。分桶不错加速数据采样,也不错进步join的性能(join的字段是分桶字段),因为分桶不错确保某个key对应的数据在一个特定的桶内(文献),是以精巧地遴荐分桶字段不错大幅度进步join的性能。等闲情况下,分桶字段不错遴荐时时用在过滤操作或者join操作的字段。

咱们不错使用set.hive.enforce.bucketing = true启用分桶诞生。

当使用分桶表时,最好将bucketmapjoin绮丽诞生为true,具体设立参数为:

CREATE TABLE table_name  PARTITIONED BY (partition1 data_type, partition2 data_type,….) CLUSTERED BY (column_name1, column_name2, …)  SORTED BY (column_name [ASC|DESC], …)]  INTO num_buckets BUCKETS; 
4.对中间数据启用压缩

复杂的Hive查询等闲会退换为一系列多阶段的MapReduce功课,况兼这些功课将由Hive引擎相接起来以完成总共查询。因此,此处的“中间输出”是指上一个MapReduce功课的输出,它将用作下一个MapReduce功课的输入数据。

压缩不错权贵减少中间数据量,从而在里面减少了Map和Reduce之间的数据传输量。

咱们不错使用以下属性在中间输出上启用压缩。

set hive.exec.compress.intermediate=true; set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec; set hive.intermediate.compression.type=BLOCK; 

为了将最终输出到HDFS的数据进行压缩,不错使用以下属性:

set hive.exec.compress.output=true; 

底下是一些不错使用的压缩编解码器

org.apache.hadoop.io.compress.DefaultCodec org.apache.hadoop.io.compress.GzipCodec org.apache.hadoop.io.compress.BZip2Codec com.hadoop.compression.lzo.LzopCodec org.apache.hadoop.io.compress.Lz4Codec org.apache.hadoop.io.compress.SnappyCodec 
5.Map端JOIN

map端join适用于当一张表很小(不错存在内存中)的情况,即不错将小表加载至内存。Hive从0.7运行复古自动转为map端join,具体设立如下:

SET hive.auto.convert.join=true; --  hivev0.11.0之后默许true SET hive.mapjoin.smalltable.filesize=600000000; -- 默许 25m SET hive.auto.convert.join.noconditionaltask=true; -- 默许true,是以不需要指定map join hint SET hive.auto.convert.join.noconditionaltask.size=10000000; -- 界限加载到内存的表的大小 

一朝开启map端join设立,Hive会自动查验小表是否大于hive.mapjoin.smalltable.filesize设立的大小,如若大于则转为平日的join,如若小于则转为map端join。

对于map端join的旨趣,如下图所示:

率先,Task A(客户端土产货推行的task)细腻读取小表a,并将其转成一个HashTable的数据结构,写入到土产货文献,之后将其加载至散播式缓存。

然后,Task B任务会启动map任务读取大表b,在Map阶段,字据每札记载与散播式缓存中的a表对应的hashtable关系,并输出扫尾

提防:map端join莫得reduce任务,是以map平直输出扫尾,即有些许个map任务就会产生些许个扫尾文献。

6.向量化

Hive中的向量化查询推行大大减少了典型查询操作(如扫描,过滤器,团聚和衔尾)的CPU使用率。

尺度查询推行系协调次贬责一瞥,在贬责下一瞥之前,单行数据会被查询中的总共运算符进行贬责,导致CPU使用恶果至极低。在向量化查询推行中,数据行被批贬责在通盘(默许=> 1024行),默示为一组列向量。

要使用向量化查询推行,必须以ORC门径(CDH 5)存储数据,并诞生以下变量。

SET hive.vectorized.execution.enabled=true 

在CDH 6中默许启用Hive查询向量化,启用查询向量化后,还不错诞生其他属性来诊疗查询向量化的形状,具体不错参考cloudera官网。

7.谓词下推

默许生成的推行诡计会在可见的位置推行过滤器,但在某些情况下,某些过滤器抒发式不错被推到更接近初次看到此特定数据的运算符的位置。

比如底下的查询:

select     a.*,     b.*  from      a join b on (a.col1 = b.col1) where a.col1 > 15 and b.col2 > 16 

如若莫得谓词下推,则在完成JOIN贬责之后将推行过滤条款**(a.col1> 15和b.col2> 16)**。因此,在这种情况下,JOIN将率先发生,况兼可能产生更多的行,然后在进行过滤操作。

使用谓词下推,这两个谓词**(a.col1> 15和b.col2> 16)**将在JOIN之前被贬责,因此它可能会从a和b中过滤掉衔尾中较早贬责的大部分数据行,因此,提议启用谓词下推。

通过将hive.optimize.ppd诞生为true不错启用谓词下推。

SET hive.optimize.ppd=true 
8.输初学径遴荐

Hive复古TEXTFILE, SEQUENCEFILE, AVRO, RCFILE, ORC,以及PARQUET文献门径,不错通过两种形状指定表的文献门径:

CREATE TABLE … STORE AS :即在建表时指定文献门径,默许是TEXTFILE ALTER TABLE … [PARTITION partition_spec] SET FILEFORMAT :修改具体表的文献门径

如若未指定文献存储门径,则默许使用的是参数hive.default.fileformat设定的门径。

如若数据存储在小于块大小的小文献中,则不错使用SEQUENCE文献门径。如若要以减少存储空间并提高性能的优化形状存储数据,则不错使用ORC文献门径,而当列中嵌套的数据过多时,Parquet门径会很有效。因此,需要字据领有的数据详情输入文献门径。

9.启动严格模式

如若要查询分区的Hive表,但不提供分区谓词(分区列条款),则在这种情况下,将针对该表的总共分区发出查询,这可能会至极耗时且占用资源。因此,咱们将底下的属性界说为strict,以迷惑在分区表上未提供分区谓词的情况下编译器将激发诞妄。

SET hive.partition.pruning=strict 
10.基于资本的优化

Hive在提交最终推行之前会优化每个查询的逻辑和物理推行诡计。基于资本的优化会字据查询资本进行进一步的优化,从而可能产生不同的有缱绻:比如奈何决定JOIN的法例,推行哪种类型的JOIN以及并行度等。

不错通过诞生以下参数来启用基于资本的优化。

set hive.cbo.enable=true; set hive.compute.query.using.stats=true; set hive.stats.fetch.column.stats=true; set hive.stats.fetch.partition.stats=true; 

不错使用统计信息来优化查询以提高性能。基于资本的优化器(CBO)还使用统计信息来比拟查询诡计并遴荐最好诡计。通过稽查统计信息而不是运行查询,恶果会很高。

齐集表的列统计信息:

ANALYZE TABLE mytable COMPUTE STATISTICS FOR COLUMNS; 

稽查my_db数据库中my_table中my_id列的列统计信息:

DESCRIBE FORMATTED my_db.my_table my_id 
论断

 

本文主要共享了10个Hive优化的基本手段,但愿大致为你优化Hive查询提供一个基本的念念路。再次感谢你的阅读,但愿本文对你有所匡助。

 






栏目分类

热点资讯

相关资讯