HIVE优化:语句、参数、表结构优化

文章目录

*

+ map相关配置
+ reduce相关配置
+ 表结构
+
* 分区
* 分桶
* 索引
* 列筛选
+ 语句优化
+
* 大表join小表:Replication
* count(distinct)
* 表过滤
* left semi join
* join倾斜
* groupby倾斜
+ 参数优化
+
* with语句
* 向量运算
* Hint
* mapjoin
* map端预聚合
* 文件压缩
* 合并小文件
* 作业并行
* 相关性优化
* 本地执行
* Fetch抓取
* join倾斜
* groupby倾斜
* 其他
+ 连接优化器
+ 其他相关
+
* 查看SQL执行计划
* show:查看信息
* desc:描述库表信息
* load:数据加载
* export命令
* 有关窗口函数的执行计划

show conf 值名

:查看配置项当前的值,如 show conf 'hive.execution.engine'

map相关配置

  • 在默认情况下Map的个数defaultNum=目标文件或数据的总大小totalSize/hdfs集群文件块的大小blockSize。
  • 当用户指定mapred.map.tasks,即为用户期望的Map大小,用expNum表示,这个期望值计算引擎不会立即采纳,它会获取mapred.map.tasks与defaultNum的较大值,用expMaxNum表示,作为待定选项。
  • 获取文件分片的大小和分片个数,分片大小为参数mapred.min.split.size 和blockSize间的较大值,用splitMaxSize表示,将目标文件或数据的总大小除以splitMaxSize即为真实的分片个数,用realSplitNum表示。
  • 获取realSplitNum与expMaxNum较小值则为实际的Map个数。

减少Map个数,需要增大 mapred.min.split.size的值,减少 mapred.map.tasks的值;
增大Map个数,需要减少 mapred.min.split.size的值,同时增大 mapred.map.tasks的值。

reduce相关配置

  • mapred.reduce.tasks:设置Reducer的数量,默认值是-1,代表由系统根据需要自行决定Reducer的数量。
  • hive.exec.reducers.bytes.per.reducer:设置每个Reducer所能处理的数据量,在Hive 0.14版本以前默认是1000000000(1GB), Hive 0.14及之后的版本默认是256MB。输入到Reduce的数据量有1GB,那么将会拆分成4个Reducer任务。
  • hive.exec.reducers.max:设置一个作业运行的最大Reduce个数,默认值是999。
  • hive.multigroupby.singlereducer:表示如果一个SQL 语句中有多个分组聚合操作,且分组是使用相同的字段,那么这些分组聚合操作可以用一个作业的Reduce完成,而不是分解成多个作业、多个Reduce完成。这可以减少作业重复读取和Shuffle的操作。
  • hive.mapred.reduce.tasks.speculative.execution:表示是否开启Reduce 任务的推测执行。即系统在一个Reduce 任务中执行进度远低于其他任务的执行进度,会尝试在另外的机器上启动一个相同的Reduce任务。
  • hive.optimize.reducededuplication:表示当数据需要按相同的键再次聚合时,则开启这个配置,可以减少重复的聚合操作。
  • hive.vectorized.execution.reduce.enabled:表示是否启用Reduce任务的向量化执行模式,默认是true。MapReduce计算引擎并不支持对Reduce阶段的向量化处理。
  • hive.vectorized.execution.reduce.groupby.enabled:表示是否移动Reduce任务分组聚合查询的向量化模式,默认值为true。MapReduce计算引擎并不支持对Reduce阶段的向量化处理。

自动计算 reduce个数=min(hive.exec.reducers.max,总数据量大小/hive.exec.reducers.bytes.per.reducer)
或者通过 mapred.reduce.tasks参数手动指定reduce个数
每个reduce都会生成一个文件;reduce的初始启动也会消耗资源:并不是越多越好;

表结构

分区

where条件是在map端过滤,分区筛选在输入阶段过滤;在hdfs上一个分区对应一个目录;对常用字段使用分区字段,比如日期,筛选某天的数据速度显著提升;

分桶

分桶能够对原有表或者分区所存储的数据进行重新组织,使得通过分桶的方式能够快速过滤掉大量不需要遍历的文件。分桶是对文件过滤,一般使用hash模余,每个记录存储到桶的算法: 记录所存储的桶=mod(hash(分桶列的值),4)
hash表示Hash函数,获取分桶列的值对应的哈希值;mod表示取余函数。
如果查询字段为分桶字段,能快速定位条件所在记录位置,而无须全表扫表,类似索引。对于大表,可以快速缩短读取数据时间,同时也能优化表的链接。比如在两表 JOIN中,相同桶的数据进行join可以节约时间。(不是一个桶的数据join不上)
可以使用 hdfs dfs -ls 表路径查看表在HDFS的存储。
使用桶的Map连接要保证连接的两张表的分桶数之间是倍数关系。
如果两个表的某字段分桶是10个,在两个表使用该字段关联join时,启用6个reduce

索引

Hive的索引在Hive 3.0版本中被废弃,可以使用两种方式进行替换:

  • 物化视图(Materialized views)。这个概念对于使用Oracle的开发者并不陌生,通过使用物化视图,可以达到类似hive索引的效果,该特性在Hive 2.3.0版本中引入。
  • 使用ORC/Parquet的文件存储格式,也能够实现类似索引选择性扫描,快速过滤不需要遍历的block,这是比分桶更为细粒度的过滤。
列筛选

ORC/Parquet中存储了文件定义的Schema, ORC/Parquet可以通过Schema直接读取表所在的列,以达到列过滤的目的。
在spark中,rdd需要对每一行按分隔符分割筛选,DataFrame有表结构可直接筛选对应数据列。

语句优化

大表join小表:Replication

HIVE中表连接的两种方式,Repartition连接和Replication连接。
Repartition连接
发生在Shuffle和Reduce阶段。一般如果不特别做其他声明,通常提到的连接就是Repartition连接。Map的任务读取A、B两个表的数据,将按连接条件发往相同的Reduce,在Reduce中计算合并的结果。

Replication连接
发生在Map阶段,Replication连接在Map阶段完成连接操作,相比发生在Shuffle阶段的Repartition连接,可以减少从HDFS读取表的次数,可以在Map 阶段实现连接时不匹配条件的记录行的过滤,减少下游网络传输的数据量和下游计算节点处理的数据量。
Replication 连接在操作时会将一个表的数据复制到各个Map 任务所在的节点并存储在缓存中,如果连接的两个表都是数据量庞大的表,会带来较大的性能问题,仅适用于两表连接中有一张小表的情况。
Replication连接根据实现的不同表连接可以分为:

  • 普通的MapJoin:对使用的表类型无特殊限制,只需要配置相应的Hive配置。
  • Bucket MapJoin:要求使用的表为桶表。hash模余相同的值会被分发到同一个桶。
  • Skewed MapJoin:要求使用的表为倾斜表。
  • Sorted Merge Bucket MapJoin:要求使用的表为桶排序表。

普通mapjoin


set hive.ignore.mapjoin.hint=false;
select  t2.product_type
    ,sum(t1.salses) as sum_sale
from sales_table t1
join dim_product_info t2
on t1.product_id = t2.product_id
group by t2.product_type

在Hive中使用common map join有几种方式,方式一是使用MapJoin的hint语法。需要注意的是要关闭忽略hint的配置项,否则该方法不会生效,即 set hive.ignore.mapjoin.hint=false;

可使用Hive配置MapJoin。使用Hive配置需要使用到以下配置:

  • hive.auto.convert.join:在Hive 0.11版本以后,默认值为true,表示是否根据文件大小将普通的repartition连接将化为Map的连接。
  • hive.smalltable.filesize/hive.mapjoin.smalltable.filesize:默认值为25000000(bytes)。两个配置表示的含义都是当小表的数据小于该配置指定的阀值时,将尝试使用普通repartition连接转化Map连接。该配置需要和hive.auto.convert.join配合使用。

Map Join相关的Hive配置如下:

  • hive.mapjoin.localtask.max.memory.usage:默认值为0.9。表示小表保存到内存的哈希表的数据量最大可以占用到本地任务90%的内存,如果超过该值,则表示小表的数据量太大,无法保存到内存中。
  • hive.mapjoin.followby.gby.localtask.max.memory.usage:默认值是0.55。表示如果在MapJoin之后还有group by的分组聚合操作,本地任务最大可以分配当前任务55%的内存给哈希表缓存数据,如果缓存的数据大于该值,表示停止当前本地任务。在优化时,如果分组聚合后的数据会大幅度地缩小,可以适当提高该阀值,以提升内存可以缓存的数据量,如果分组聚合后的数据不降反增,则需要适当调低该比值防止内存溢出,导致作业失败。

倾斜连接:

set hive.optimize.skewjoin=true;

set hive.skewjoin.key=100000;
select  t2.product_type
    ,t1.salses
from sales_table t1
join dim_product_info t2
on t1.product_id = t2.product_id

创建倾斜表:通过在创建表时指定数据倾斜键,将指定的数据键分割成单独的数据文件或者目录,这样可以加快数据过滤从而提供作业的运行速度。


CREATE TABLE student_info_bucket (s_no STRING, s_score bigint)

SKEWED BY (s_score) ON (96,97)

STORED AS DIRECTORIES;

倾斜键的数据存储在Hive_DEFAULT_LIST_BUCKETING_DIR_NAME目录中(比如上面的96和97),而其他数据则存储在与该目录同一级的文件目录下。
Hive中与SkewedJoin相关的配置如下:

  • hive.optimize.skewjoin:默认值是false,表示是否优化有倾斜键的表连接。如果为true, Hive将为连接中的表的倾斜键创建单独的计划。
  • hive.skewjoin.key:默认值为100000。如果在进行表连接时,相同键的行数多于该配置所指定的值,则认为该键是倾斜连接键。
  • hive.skewjoin.mapjoin.map.tasks:默认值为10000。倾斜连接键,在做MapJoin 的Map任务个数。需要与hive.skewjoin.mapjoin.min.split一起使用。
  • hive.skewjoin.mapjoin.min.split:默认值为33554432,即32MB。指定每个split块最小值,该值用于控制倾斜连接的Map任务个数。
count(distinct)

语句1:
select count(distinct age) as dis_cnt from user_info
count(distinct)会将同一个key的数据交给一个reduce处理,数据数据记录行多,跑批相对耗时长。以上语句由一个MR处理完成。
语句2:

select count(1) as dis_cnt
from (select age from user_info group by age) t

语句2执行计划由两个MR构成;
age年龄枚举值较少,map段预聚合,shuffle到reduce端数据量整体还是比较少,两者区别不是很明显。count(distinct)计算使用一个MR计算耗时可能会更短些。
如果key数据量比较大的情况下,两个MR处理相对会快些,比如大企业用户规模较大,查看近1年的用户活跃数(月表,用户id去重),如果使用count(distinct),如果每个月活跃去重在1亿,一年意味着大概有12亿的数据交由1个reduce去重计数。这时候交由两个MR处理,多处一个MR的开销相比时效提升几乎可以忽略不计。
在Hive 3.0中即使遇到数据倾斜,语句1将 hive.optimize.countdistinct设置为true,写法也能达到语句2的效果。

表过滤

表过滤是指过滤掉同一个SQL 语句需要多次访问相同表的数据,将重复的访问操作过滤掉并压缩成只读取一次。表过滤的常见操作就是使用multi-group-by语法替换多个查询语句求并集的句式。

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
explain
insert into table insert_table partition(tp)
select s_age, min(s_birth) as birth, 'max' as label
from user_info
group by s_age
union all
select s_age, max(s_birth) as birth, 'min' as label
from user_info
group by s_age

上面的sql,user_info表会读两次

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
explain
from user_info
insert into table student_stat partition(tp)
select s_age, min(s_birth) as birth, 'max' as label
group by s_age
insert into table  student_stat partition(tp)
select s_age, max(s_birth) as birth, 'min' as label
group by s_age;
left semi join

类似与mysql的exists语句,只要找到了便打断不再往下找;而join会遍历试着匹配每一个能匹配上的key。

select id,t1.field1,t2.field2
from table_a t1
left semi join table_b t2
on t1.id = t2.id

等同于

select id,t1.field1,t2.field2
from table_a t1
where id in (
    select id from table_b
)
join倾斜

此外我们也可以把倾斜键单独拉出来处理,比如下面一段sql

select t1.field1,t1.mobile_no,t2.field2
from table_a t1
left join table_b t2
on t1.mobile_no=t2.mobile_no

如果table_a表的mobile手机号存在大量缺失,那那么我们可以把这部分单独拉出来处理,比如修改为:

select t1.fields,t1.mobile_no,t2.field2
from table_a t1
left join table_b t2
on t1.mobile_no=t2.mobile_no
where t1.mobile_no is not null
union all
select t1.fields,null as mobile,null as field2
from table_a
where mobile_no is null

或者我们也可以这样:

select t1.field1,t1.mobile_no,t2.field2
from table_a t1
left join table_b t2
on nvl(t1.mobile_no,rand())=t2.mobile_no

    and t2.mobile_no is not null

该方法虽然打散了null,不过mobile_no为null部分仍然经历了shuffle和reduce过程

groupby倾斜

原sql为:

select key_name,sum(val) as sum_val
from table_name
group by key_name

我们可以在第一个stage添加随机数key,改写为:

select key_name
    ,sum(sum_val) as sum_val
from
(
    select key_name
        ,ceiling(rand() * 99) as rnk
        ,sum(val) as sum_val
    from table_name
    group by key_name,ceiling(rand() * 99)
) t
group by key_name

类似于添加groupby倾斜参数

参数优化

with语句

hive的with语句默认生成with语句一个视图,并不会把数据物化。使用with语句代码看起来相对简洁;如果sql中with的代码块有多次调用,会重复生成with执行计划,不一定会提高执行效率。
在高版本中,with语句可物化,参数为: hive.optimize.cte.materialize.threshold,参数默认是-1关闭。如果开启(大于0),比如n,当with…as语句被引用n次以上,会物化with生成的表,对应的with语句只执行一次。


set hive.optimize.cte.materialize.threshol=2
with tmp_tb1 as (
    select user_id,register_date from tb
),tmp_tb2 as (
    select user_id from tb2 where dt = '20220918' group by userid
)
select user_id,register_date from tmp_tb1
union all

select t2.user_id,'20220918' as register_date
from tmp_tb2 t2 left join tmp_tb1 t1
on t2.user_id=t1.user_id
where t1.user_id is null
向量运算

hive开启向量计算,将一次处理一条数据变为一次处理1万条数据,以此提高程序的性能
hive.vectorized.execution.enabled:表示是否开启向量模式,默认值为 false
开启: set hive.vectorized.execution.enabled = true;

目前MapReduce计算引擎只支持Map端的向量化执行模式,Tez和Spark计算引擎可以支持Map和Reduce端的向量化执行模式

Hint

hive.ignore.mapjoin.Hint:是否忽略SQL中MapJoin的Hint关键,在Hive 0.11版本之后默认值为true,即开启忽略Hint的关键字。如果要使用MapJoin的Hint关键字,要在使用前开启支持Hint语法,否则达不到预期的效果。
Hint关键字,比如 /*+ MAPJOIN(smalltable)*/

mapjoin

大表join小表
hive.auto.convert.join:是否开启MapJoin自动优化,hive 0.11版本以前默认关闭, 0.11及以后的版本默认开启。
hive.smalltable.filesize or hive.mapjoin.smalltable.filesize:默认值2500000(25MB)如果大小表在进行表连接时的小表数据量小于这个默认值,则自动开启MapJoin优化。在Hive 0.8.1以前使用 hive.smalltable.filesize,之后的版本使用 hive.mapjoin.smalltable.filesize参数。

  • hive.mapjoin.optimized.hashtable:默认值是true, Hive 0.14新增,表示使用一种内存优化的哈希表去做MapJoin。由于该类型的哈希表无法被序列化到磁盘,因此该配置只能用于Tez或者Spark。
  • hive.mapjoin.optimized.hashtable.wbsize:默认值是10485760(10MB),优化的哈希表使用的是一种链块的内存缓存,该值表示一个块的内存缓存大小。这种结构对于数据相对较大的表能够加快数据加载,但是对于数据量较小的表,将会分配多余的内存。
  • hive.vectorized.execution.mapjoin.native.enabled:是否使用原生的向量化执行模式执行MapJoin,它会比普通MapJoin速度快。默认值为False。

mapjoin失效情况
mapjoin在left或者right连接,小表为主表时会失效。
如下:小表 left join,大表开启了两个map,对于小表为2这一行,在上面这个map,由于没有2,大表为null,但在第二个map时,大表存在2这行有记录。这样就会出现一个问题,在大表某一个map不存在2这条记录时,大表的这个字段是为null还是2?
不可操作,所以该种情况mapjoin失效

HIVE优化:语句、参数、表结构优化
; map端预聚合

Map端聚合通常指代实现Combiner类。Combiner也是处理数据聚合,不同于Reduce是聚合集群的全局数据。Combiner聚合是Map阶段处理后的数据,处理类似于spark里边的reduceByKey。
Map预聚合目标可以减少Shuffle数据量。如果数据经过聚合后不能明显减少,那就是浪费机器的I/O资源。

  • hive.map.aggr:是否开启Map任务的聚合,默认值是true。
  • hive.map.aggr.hash.min.reduction:是一个阈值,默认值是0.5。
  • hive.groupby.mapaggr.checkinterval:默认值是100000。Hive在启用Combiner时会尝试取这个配置对应的数据量进行聚合,将聚合后的数据除以聚合前的数据,如果小于hive.map.aggr.hash.min.reduction会自动关闭。
  • hive.map.aggr.hash.percentmemory:默认值是0.5。该值表示在进行Mapper端的聚合运行占用的最大内存。例如,分配给该节点的最大堆(xmx)为1024MB,那么聚合所能使用的最大Hash表内存是512MB,如果资源较为宽裕,可以适当调节这个参数。
  • hive.map.aggr.hash.force.flush.memory.threshold:默认值是0.9。该值表示当在聚合时,所占用的Hash表内存超过0.9,将触发Hash表刷写磁盘的操作。例如Hash表内存是512MB,当Hash表的数据内存超过461MB时将触发Hash表写
文件压缩

减少Shuffle数据量,开启压缩同时意味着有解压缩消耗,一般适用于大型作业。
开启文件作业的压缩只要将 hive.exec.compress.intermediate参数设置为 true
压缩如果要是MapReduce中起作用,前提是需要配置mapred.output.compression. codec和mapred.output.compression两个属性。

合并小文件
  • map执行前合并文件
    set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
    我们假设表a通过sparksql默认参数写入到hdfs(shuffle.partitions=200),有200个文件块,每个文件块大小只有1m;开启该参数后,map时只有一个task,会将小文件进行合并;如果没开启,每个文件块一个task;
  • 启用hive.merge.mapfile参数,默认启用,合并只有Map任务作业的输出文件;
    比如: select id,name,sale from tablename where sale>1000这条sql语句只有map操作
  • 启用hive.merge.mapredfiles参数,默认启用,合并MapReduce作业最终的输出文件;
    比如: select age,count(1) as cnt from tablename group by age在reduce后,默认每个reducetask会生成一个文件快,如果文件块小则可以通过该参数将文件进行合并;
  • 设置hive.merge.smallfiles.avgsize参数,默认16MB,当输出的文件小于该值时,启用一个MapReduce任务合并小文件;
  • 设置hive.merge.size.per.task参数,默认256MB,是每个任务合并后文件的大小。一般设置为和HDFS集群的文件块大小一致。 set hive.merge.size.per.task = 268435456;

文件太多会增加map-task开销;同事如果reduce个数太多,每个reduce会输出一个文件也会增加下游任务map读取开销;

作业并行

hive.optimize.countdistinct:默认值为true, Hive 3.0新增的配置项。当开启该配置项时,去重并计数的作业会分成两个作业来处理这类SQL,以达到减缓SQL的数据倾斜作用。
hive.exec.parallel:默认值是False,是否开启作业的并行。默认情况下,如果一个SQL被拆分成两个阶段,如stage1、stage2,假设这两个stage没有直接的依赖关系,还是会采用窜行的方式依次执行两个阶段。如果开启该配置,则会同时执行两个阶段。在资源较为充足的情况下开启该配置可以有效节省作业的运行时间。比如使用union all语句,union前后sql子句是没有依赖可以并行执行;

select 'label1' as label
    ,sum(val) as val
from tablename1
union all
select 'label2' as label
    ,sum(val) as val
from tablename2
相关性优化

hive.optimize.correlation:默认值为false,打开该配置可以减少重复的Shuffle操作。
比如sql,join已经按product_type分区,groupby没必要重新Shuffle。

select t2.product_type,sum(t1.sale) as sale
from dw_cus_sale_ptd t1
join dim_product_info t2
on t1.product_type = t2.product_type
group by t2.product_type
</code></pre>
<h5>本地执行</h5>
<p>文件数量大,使用分布式计算,多台机器并行计算可以显著减少计算时间。当hive数据量非常小,查询触发执行任务消耗的时间可能会比实际job的执行时间要多的多。这种情况,hive可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显减少。
相关参数:<br> <code>set hive.exec.mode.local=true</code>开启本地mr<br> <code>set hive.exec.mode.local.auto.inputbytes.max=5000000</code>设置local mr的最大数据数据量,当输入数据量小于这个值时采用local mr的方式,默认为134217728,即128M。<br> <code>set hive.exec.mode.local.auto.input.files.max=</code>12设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4。
Fetch抓取

Fetch抓取:hive中某些情况可以不必使用mr计算,例如: select * from table1。这种情况,hive可以简单读取文件输出到控制台。在hive-default.xml.tempate文件中,hive.fetch.task.conversion默认是more,老版本是minimal,这个属性修改为more后,全局查找,字段查找,limit查找不走mr计算。比如: select id,name from table name limit 1000开启参数后,这条sql语句并不会走mr计算在关系型数据库中使用 select * from table limit 10通常会全表扫描再limit。

join倾斜

hive.optimize.skewjoin=true
hive.skewjoin.key=10000可定义倾斜键界定返回,超过该值则会把该key部分单独拉起一个mr任务进行map端join逻辑加速join实际是两个MR过程,该参数不适用于out外连接,原因类同mapjoin小表作为主表失效
hive.skewjoin.mapjoin.map.task参数可以控制第二个job的mapper数量,默认是1000

groupby倾斜

set hive.map.aggr = true开启map端聚合
set hive.groupby.mapaggr.checkinterval = 100000map端聚合数据条数,如果map数据量超过该该记录数,会按记录数拆分新增task处理
set hive.groupby.skewindata=true

开启该参数,HIVE会生成的查询计划会有两个 MapReduce Job。

第一个 MapReduce Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个Reduce 做部分聚合操作并输出结果。相同的 GroupBy Key 有可能被分布到不同的 Reduce 中,负载均衡;第二个 MapReduce Job 再根据预处理的数据结果,按照 GroupBy Key 分布到 Reduce 中(这过程可以保证相同的GroupBy Key被分布到同一个Reduce中),最后完成最终的聚合操作类似于写一段sql,第一个job对key加入随机数

select key_field
    ,sum(val) as val
from
(
    select key_filed,cast(rand() * 100 as int) as rnd
        ,sum(val) as val
    from tablename
    group by key_filed,cast(rand() * 100 as int)
) t
其他
  • hive.map.groupby.sorted:在Hive 2.0以前的默认值是False,2.0及2.0以后的版本默认值为true。对于分桶或者排序表,如果分组聚合的键(列)和分桶或者排序的列一致,将会使用BucketizedHiveInputFormat。
  • hive.vectorized.execution.mapjoin.minmax.enabled:默认值为False,是否使用vector map join哈希表,用于整型连接的最大值和最小值过滤。

连接优化器

CBO(成本优化器:Cost Based Optimizer)可以基于收集到的统计信息,估算出每个表连接的组合,生成一个成本代价最低的表连接方案,预先两两结合生成中间结果集,再针对这些中间结果集进行操作。
简化表的连接,在多表连接的情况下,CBO在解析SQL子句时,会识别并抽取相同的连接谓词,并根据情况适当构造一个隐式的连接谓词作为替换,以避免高昂的表连接操作。

select tb1.id
    ,tb2.field2
    ,tb3.field3
    ,tb4.field4
from table1 tb1
join table2 tb2
on tb1.id = tb2.id
join table3 tb3
on tb2.id = tb3.id
join table4 tb4
on tb3.id = tb4.id

正常来说,tb3的join要等待tb1和tb2的join之后发生,这样无法充分利用集群计算。优化后的执行过程可能是:tb1 join tb2和tb3 join tb4同时进行。
step1:
tb1 join tb2 -> tb_tmp1
tb3 join tb4 -> tb_tmp2
step2:
tb_tmp1 join tb_tmp2

其他相关

查看SQL执行计划
  • 查看执行计划的基本信息,即explain;
  • 查看执行计划的扩展信息,即explain extended;
  • 查看SQL数据输入依赖的信息,即explain dependency;
  • 查看SQL操作相关权限的信息,即explain authorization;
  • 查看SQL的向量化描述信息,即explain vectorization。
show:查看信息
  • show databases:获取hive的库名列表。
  • show tables:获取当前库下的表名列表。
  • show partitions表名:获取表的分区列表。
  • show functions:获取当前可用函数列表。
  • show views:获取当前库下的视图列表,Hive 2.2版本中新增。
  • show tblproperties:获取某个表的表配置属性。
  • show create table表名:获取某个表的完整建表语句。
  • show column from表名:获取表的所有字段名。
  • show locks:获取某个库、表或者某个表的分区的锁信息。
  • show transactions:获取库内的事务信息。
  • show compactions:获取已经被压缩或正在被压缩的表/分区的压缩信息。
  • show conf '值名':查看配置项当前的值,如show conf 'hive.execution.engine'。
  • show table extended like表名:获取表的大部分信息,包括数据存储位置、输入/输出格式、列基本信息和表的配置信息等
  • desc:描述库表信息
  • desc database库名,用于获取库的描述,包括库的存储位置及权限信息。
  • desc [extended|formatted]表/分区,用于获取表或者某个表的分区的详细信息,比show table extend更加具体。

load:数据加载

将本地/集群上的某个文件直接插入表/分区

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename
[PARTITION (partcol1=val1, partcol2=val2 ...)]

export命令

将表或分区的数据连同元数据导出到指定的输出位置。

EXPORT TABLE tablename [PARTITION (part_column="value"[, ...])]
TO 'export_target_path' [ FOR replication('eventid') ]

有关窗口函数的执行计划

select field1
    ,field2
    ,row_number() over(partition by field2 order by field3 desc) as rnk1
    ,row_number() over(partition by field2 order by field4 desc) as rnk2
    ,row_number() over(partition by field2 order by field5 desc) as rnk5
from dw_cus_safe.dw_cus_user_login_info

该窗口函数没有其他特殊情况,比如小文件合并带来的mr增加,每个row_number都是一个mr,三个stage顺序依赖;窗口函数执行过程中的key即是partition by的字段,这里是field2;

推荐:《Hive性能调优实战》

Original: https://blog.csdn.net/me_to_007/article/details/126921955
Author: 爱弥儿er
Title: HIVE优化:语句、参数、表结构优化

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/817375/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球