万有斥力 发表于 2024-7-15 16:14:25

Hive 调优(包罗hive全部调优方式 看这一篇就够了)

Hive 调优

hive官方设置url: https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties
1、调优方式

hive参数配置的意义: 开发Hive应用/调优时,不可避免地需要设定Hive的参数。设定Hive的参数可以调优HQL代码的执行效率,或帮助定位问题。然而实践中经常遇到的一个问题是,为什么我设定的参数没有起作用?这是对hive参数配置几种方式不了解导致的!

hive参数设置范围(从大到小): 配置文件 > 命令行参数 > set参数声明
hive参数设置优先级(从高优先级到低优先级): set参数声明 > 命令行参数 > 配置文件

注意: 在工作中,推荐使用set参数声明,因为最简单最方便。而且同一个大数据集群除了你了还有其他的人或者项目组在使用。
2、hive数据压缩

Hive底层是运行MapReduce,以是Hive支持什么压缩格式本质上取决于MapReduce。
2.1 压缩对比

   在后续可能会使用GZ(GZIP), 包管压缩后的数据更小, 同时压缩和解压的速度比较OK的,
但是大部门的选择重要会选择另一种压缩方案, snappy, 此种方案可以包管在公道的压缩比下, 拥有更高的解压缩的速度,在大数据领域中重要是关注数据的处理速度
http://google.github.io/snappy/
On a single core of a Core i7 processor in 64-bit mode, Snappy compresses at about 250 MB/sec or more and decompresses at about 500 MB/sec or more.
https://img-blog.csdnimg.cn/direct/9e25933ab08e4f79981c4cb0f6fbd814.png
2.2 开启压缩

   开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量. 当Hive将输出写入到表中时,输出内容同样可以举行压缩。用户可以通过在查询语句或执行脚本中设置这个值为true,来开启输出效果压缩功能。

-- 创建数据库
create database hive05;
-- 使用库
use hive05;


-- 开启压缩(map阶段或者reduce阶段)
--开启hive支持中间结果的压缩方案
set hive.exec.compress.intermediate; -- 查看默认
set hive.exec.compress.intermediate=true ;
--开启hive支持最终结果压缩
set hive.exec.compress.output; -- 查看默认
set hive.exec.compress.output=true;

--开启MR的map端压缩操作
set mapreduce.map.output.compress; -- 查看默认
set mapreduce.map.output.compress=true;
--设置mapper端压缩的方案
set mapreduce.map.output.compress.codec; -- 查看默认
set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;

-- 开启MR的reduce端的压缩方案
set mapreduce.output.fileoutputformat.compress; -- 查看默认
set mapreduce.output.fileoutputformat.compress=true;
-- 设置reduce端压缩的方案
set mapreduce.output.fileoutputformat.compress.codec; -- 查看默认
set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
--设置reduce的压缩类型
set mapreduce.output.fileoutputformat.compress.type; -- 查看默认
set mapreduce.output.fileoutputformat.compress.type=BLOCK;
3、hive数据存储

3.1 行列存储原理

https://img-blog.csdnimg.cn/direct/97b810231e5246149f96f9599e0303d5.png
https://img-blog.csdnimg.cn/direct/9c708bba61be4c929669ed36095c796a.png
行存储的特点: 将数据以行的形式整体进行存放
列存储的特点: 将相同字段的值作为整体放在一起进行存放

行存储:
        优点: 如果要查询整行数据内容,速度比较快。适合进行数据的insert/update操作
        缺点: 如果数据分析的时候,只想针对某几个字段进行处理,那么这个效率低。因为会将不需要的字段内容也会加载出来
        使用: textfile和sequencefile
       
列存储:
        优点: 如果数据分析的时候,只想针对某几个字段进行处理,那么效率高,因为你要什么,我就给你返回什么
        缺点: 如果要查询整行数据内容,速度比较慢。不适合进行数据的insert/update操作
        使用: orc和parquet。推荐使用orc
       
注意: 在工作中推荐ORC+Snappy压缩一起使用,更加能够减少HDFS的磁盘占用。
格式:
        stored as orc -- 设置数据的存储格式
        tblproperties ("orc.compress"="SNAPPY"); -- 设置数据的压缩格式
ORC
https://img-blog.csdnimg.cn/direct/be8228fd189449f387d7172aca8f7fe0.png
3.2 存储压缩比

-- 数据的存储和压缩方式
-- textfile:占用空间18.13 MB(如果是HDFS需要乘以3)
create table log_text(
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
stored as textfile; -- 表默认的存储格式就是不压缩并且使用行式存储中的textfile存储

-- 导入数据
load data inpath '/dir/log.data' into table log_text;

-- 数据验证
select * from log_text;
select count(*) as cnt from log_text;

-- 列式存储:ORC,占用空间2.78 MB
create table log_orc(
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
stored as orc;

-- 加载数据
insert overwrite table log_orc select * from log_text;
select count(*) as cnt from log_orc;

-- 列式存储:ORC+snappy。占用空间3.75 MB,这里相对ORC反而多占用了1MB空间,是因为数据量太小,同时压缩以后,压缩文件里面需要存储和压缩相关元数据信息(例如:使用的压缩算法具体是哪一个)
-- https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL
create table log_orc_snappy(
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
stored as orc -- 设置数据的存储格式
tblproperties ("orc.compress"="SNAPPY"); -- 设置数据的压缩格式

-- 加载数据
insert overwrite table log_orc_snappy select * from log_text;
select count(*) as cnt from log_orc_snappy;

-- 列式存储:parquet。占用空间13.09MB
create table log_orc_parquet(
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
stored as parquet;

-- 加载数据
insert overwrite table log_orc_parquet select * from log_text;
select count(*) as cnt from log_orc_parquet;
   拓展dfs -du -h
-- 查看hdfs文件大小除了去页面查看,还可以通过命令
dfs -du -h '/user/hive/warehouse/hive05.db/log_text/log.data' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_orc/000000_0' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_orc_snappy/000000_0' ;
dfs -du -h '/user/hive/warehouse/hive05.db/log_parquet/000000_0' ;
4、fetch抓取

核心点: 在执行SQL, 能不走MR, 尽量不走MR
追念, 在之前执行什么样查询的SQL的时候,没有走MR呢?
1) 全表扫描
2) 查询某个列数据
3) 执行一些简单查询操作
4) 执行limit操作
而这些操作, 没有走MR原因, 就是hive默认以及开启本地抓取的策略方案:
hive.fetch.task.conversion:   设置本地抓取策略
可选:
        more (默认值): 可以保证在执行全表扫描、查询某几个列、简单的limit查询、简单的条件过滤不会变成MapReduce
        minimal: 可以保证在执行全表扫描、查询某几个列、简单的limit查询不会变成MapReduce
        none: 全部的HiveSQL语句都要变成MapReduce
示例:
-- 不会变成MapReduce几类SQL演示
-- 默认是more,底层自动调优
set hive.fetch.task.conversion;-- 默认值more
select * from log_text; -- 全表扫描
select url from log_text; -- 查询某个列的数据
select * from log_text where city_id=-10; -- 简单的where过滤查询
select * from log_text limit 10; -- 执行limit程序

select * from log_text order by url desc limit 100,10; -- 复杂limit会变成MapReduce

set hive.fetch.task.conversion=minimal;
set hive.fetch.task.conversion;
select * from log_text; -- 全表扫描
select url from log_text; -- 查询某个列的数据
select * from log_text limit 10; -- 执行limit程序
select * from log_text where city_id=-10; -- 简单的where过滤查询


set hive.fetch.task.conversion=none;
set hive.fetch.task.conversion; -- 这里也要变成MapReduce
select * from log_text; -- 全表扫描
select url from log_text; -- 查询某个列的数据
select * from log_text limit 10; -- 执行limit程序
select * from log_text where city_id=-10; -- 简单的where过滤查询
5、本地模式

核心点:让MR能走本地模式, 尽量走本地MR(明确话: 小活能自己干就不要麻烦别人)
如何开启:
        set hive.exec.mode.local.auto=true;默认值为: false

开启本地模式后, 在什么情况下执行本地MR:   只有当输入的数据满足以下两个特性后, 才会执行本地MR
        set hive.exec.mode.local.auto.inputbytes.max=51234560;   
                默认为128M。设置本地MR最大处理的数据量
        set hive.exec.mode.local.auto.input.files.max=10;
                默认值为4。设置本地MR最大处理的文件的数量
示例:
-- 4.开启本地mr(默认false,如果小数据任务进行调优开启,小任务能自己干就自己干)
set hive.exec.mode.local.auto;-- 默认关闭
set hive.exec.mode.local.auto=false; -- 手动关闭
set hive.exec.mode.local.auto=true; -- 手动开启

--设置local mr的最大输入数据量,当输入数据量小于这个值时采用localmr的方式,默认为134217728,即128M
set hive.exec.mode.local.auto.inputbytes.max;-- 查看
set hive.exec.mode.local.auto.inputbytes.max=134217728;

--设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4
set hive.exec.mode.local.auto.input.files.max;-- 查看
set hive.exec.mode.local.auto.input.files.max=4;

-- 执行sql语句
-- 没有开启本地执行24秒,开启后1.5秒
select * from log_text order by city_id desc;

-- 注意: 有的同学开启本地模式后执行上述sql语句,会报code 2...错误
-- 错误: Error while processing statement: FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
-- 如何解决? /export/server/hive/hive-env.sh修改 export HADOOP_HEAPSIZE=2048
-- 注意: 修改完后需要重启hive服务
6、join的优化操作

思考: 在通过hive执行多表查询的SQL, 最终hive翻译的MR,是如何完成join的工作的呢?
默认的join举动, 基于reduce端的join工作
思考, 请问上述join存在哪些问题?
1) 导致reduce的压力剧增, 所有的数据全部都打向reduce中
2) 当有了多个reduce后, 如果某个join字段的值出现大量的重复, 会导致大量key发往同一个reduce, 从而导致数据倾斜
那么如何解决reduce端join遇到问题? 可以通过底层map 端 join实现,还可以sql语句join之条件前过滤数据或者转换数据实现
通过 map join 即可解决掉 reduce join所出现的所有的问题, 也可以这么 mapjoin有解决数据倾斜的作用

存在什么弊端:
        小表数据需要存储在内存中, 随着mapTask越多, 存储在内存的小表数据份数也会越多
                当这个小表数据比较大的, 可能无法放置到内存中

所以说, mapJoin有一定使用范围: 仅适用于小表 和大表 进行join的情况


[*]
[*]大表和小表举行join:
   

[*] 解决方案: map join
[*] 如何开启这种操作呢?
set hive.auto.convert.join = true; -- 默认为true开启mapJoin支持
set hive.mapjoin.smalltable.filesize= 25000000;设置 小表的最大的数据量23.84m

[*] 在执行SQL, 应该将小表放置前面呢, 还是大表放置在前面呢,还是都可以呢 ?
(hive1) :要求 必须将小表在前大表在后 ,只有这样才可能走Map Join
(hive2):无所谓, 谁在前, 谁在后, 没有任何的影响, hive会自动判断


[*]
[*]大表和大表join
   

[*] 解决方案:
1) 能在join之前过滤操作, 一定要在join前过滤, 以减少join的数据量, 从而提升效率
2) 如果join字段上, 有很多的空值null值,获取其他无效数据, 这些值越多 就会导致出现数据倾斜
        方案一: 提前过滤掉
                select * from (select * from 表1 where 字段名 is not null) 别名1 join (select * from 表2 where                         字段名 is not null) 别名2 on 关联条件;
        方案二: 将null值替换为随机数, 从而减少数据倾斜影响
                select * from (select case when 字段名 is null then rand() else 字段名 endfrom 表1) 别名1 join                         (select case when 字段名 is null then rand() else 字段名 endfrom 表2) 别名2 on 关联条件;
3) 基于分桶表(大文件分为多个小文件)


7、列裁剪

Hive在读数据的时候,可以只读取查询中所必要用到的列,而忽略其他列
比方:
假设有一个表A: a b c d e   5个字段, 请查看以下SQL
selecta,b from A where a=xxx;

在这条SQL, 发现没有使用c d e 字段, 在from A表时候, 读取数据, 只需要将a列 和 b列数据读取出来即可, 不需要读取cde列字段, 这样可以减少读取的数据量, 从而提升效率
如何设置呢?
-- -=【列裁剪(只读取sql语句需要的字段,节省读取开销,提升效率)
set hive.optimize.cp=true;-- 默认就是true(在hive 2.x中无需在配置了, 直接为固定值: true)
8、分区裁剪

执行查询SQL的时候, 能在join之条件前举行条件过滤的操作, 肯定要提前过滤, 不要在join后举行过滤操作
如果操作的表是一张分区表, 那么建议肯定要带上分区字段, 以减少扫描的数据量, 从而提升效率,
比方:
select* from A join B where A.id=xxx;
优化后:
select * from (select * from A where id= xxx) A join B;
如何设置呢?
-- 7.分区裁剪
set hive.optimize.pruner=true; --默认为就是true (在hive 2.x中无需在配置了, 直接为固定值: true)
9、group by 操作

方案一:
    (1)是否在Map端进行聚合,默认为True
    set hive.map.aggr = true;
    (2)在Map端进行聚合操作的条目数目
    set hive.groupby.mapaggr.checkinterval = 100000;

方案二:官方称为 负载均衡
    (3)有数据倾斜的时候进行负载均衡(默认是false)
    set hive.groupby.skewindata = true;
    第一个MR Job中,Map的输出结果会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;
    第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce中(这个过程可以保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操作。

10、count(distinct)

说明 : count(distinct) 在数据量比较大的情况下, 效率并不高
思考: 你知道是为什么吗?
原因如下:
        请问1: 执行count操作的时候, hive翻译的MR, reduce数量是否可以有多个? 必然不会有多个, 只能有一个, 因为全局求最终结果
        此时如果执行统计的时候, 需要进行去重,那么去重工作是由reduce执行去重操作,由于reduce只有一个, 所有的数据都在一个reduce中, 此时reduce的压力比较大
               
        希望执行去重工作可能有多个reduce一起来执行操作, 此时可以将SQL优化:
                原有:
                        select count(distinct ip) from ip_tab;
                优化:
                        select
                          count(ip)
                        from
                           (select ip from ip_tab group by ip) tmp;
       
                请注意: 这样的做法, 虽然会运行两个MR, 但是当数据量足够庞大的时候, 此操作绝对是值得的, 如果数据量比较少, 此操作效率更低

-- count(distinct)优化
set hive.optimize.countdistinct; -- 默认就是true
set hive.optimize.countdistinct = true;
/*
SELECT count(DISTINCT id) FROM 大表;
结果:
SELECT count(id) FROM (SELECT id FROM 大表 GROUP BY id) a;
*/
select count(distinct devicetype) from device1;
select count(devicetype) from (select devicetype from device1 group by devicetype) a;
-- 注意: 小表拆分两个mr反而效率低,以后大表的时候才会真正提升效率
11、笛卡尔积

什么是笛卡尔积呢? 在举行join的时候, 两个表乘积之后效果就是笛卡尔积的效果
比如: 一个表有5条, 一个表有3条数据, 笛卡尔积效果就有15条数据 , 笛卡尔积中有大量数据都是无用数据
什么时候会产生笛卡尔积呢?
在多表join的时候, 关联条件缺少或者使用错误的关联条件以及将关联条件放置在where中都会导致笛卡尔积
12、动态分区

需求: 请将下面的一个分区表数据, 拷贝到另一个分区表, 包管对应区数据放置到另一个表的对应区下
如何设置呢?
作用:帮助一次性灌入多个分区的数据
参数:
        set hive.exec.dynamic.partition.mode=nonstrict;-- 开启非严格模式 默认为 strict(严格模式)
        set hive.exec.dynamic.partition=true;-- 开启动态分区支持, 默认就是true
       
可选的参数:
        sethive.exec.max.dynamic.partitions=1000; -- 在所有执行MR的节点上,最大一共可以创建多少个动态分区。
        set hive.exec.max.dynamic.partitions.pernode=100; -- 每个执行MR的节点上,最大可以创建多少个动态分区
        set hive.exec.max.created.files=100000; -- 整个MR Job中,最大可以创建多少个HDFS文件
13、如何调整map和reduce的数量

   1>是不是map数越多越好?
答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。
2>是不是包管每个map处理靠近128m的文件块,就高枕无忧了?
答案也是不肯定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。
3>是不是reduce数越多越好?
答案是否定的。如果reduce设置的过大,对整个作业会产生肯定的影响。
①过多的启动和初始化reduce也会消耗时间和资源;
②另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;
4>在什么情况下, 只能有一个reduce呢?
以下几种, 不管如何设置, 最终翻译后reduce只能有一个
​ 1) 执行order by操作
​ 2) 执行不必要group by直接聚合的操作
​ 3) 执行笛卡尔积


[*] 如何调整mapTask数量:
小文件场景:当input的文件都很小,把小文件举行合并归档,减少map数, 设置map数量:
-- 每个Map最大输入大小(这个值决定了合并后文件的数量)
    set mapred.max.split.size=256000000;
-- 一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
    set mapred.min.split.size.per.node=1;
-- 一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)
    set mapred.min.split.size.per.rack=1;
-- 执行Map前进行小文件合并默认CombineHiveInputFormat
    set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
大文件场景:当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以思量增加Map数,来使得每个map处理的数据量减少,从而提高任务的执行效率。
       举例:如果表a只有一个文件,大小为120M,但包罗几千万的记录,如果用1个map去完成这个任务,肯定是比较耗时的,
​ 这种情况下,我们要思量将这一个文件公道的拆分成多个,这样就可以用多个map任务去完成。
​ set mapred.reduce.tasks=10;
​ create table a_1 as select * from tab_info distribute by rand(123);
​ 这样会将a表的记录,随机的分散到包罗10个文件的a_1表中,再用a_1代替上面sql中的a表,则会用10个map任务去完成。
[*] 如何reduce的数量:
-- 查看reduces数量
-- 该值默认为-1,由hive自己根据任务情况进行判断。
set mapred.reduce.tasks;
set mapreduce.job.reduces;
-- (1)每个Reduce处理的数据量默认是256MB左右
set        hive.exec.reducers.bytes.per.reducer=256000000;
-- (2)每个任务最大的reduce数,默认为1009;
set        hive.exec.reducers.max=1009;

14、并行执行

​ 在执行一个SQL语句的时候, SQL会被翻译为MR, 一个SQL有可能被翻译成多个MR, 那么在多个MR之间, 有些MR之间可能不存在任何的关联, 此时可以设置让这些没有关联的MR 并行执行, 从而提升效率 , 默认是 一个一个来
如何设置:
set hive.exec.parallel=false;            --打开任务并行执行,默认关闭
set hive.exec.parallel.thread.number=8;--同一个sql允许最大并行度,默认为8。

前提:
        服务器必须有资源, 如果没有 即使支持并行, 也没有任何作用
案例:
select* from A ....
union all
select * from B ...;

例如:
        select from (select * from A group by ...) tmp1 join (select * from B group by xxx) on ...
15、严格模式

​ hive提供一种严格模式, 重要目的, 是为了限定一些 效率极低的SQL 放置其执行时间过长, 影响其他的操作
屏蔽一下操作:
1) 执行order by 不加 limit
2) 出现笛卡尔积的现象SQL
3) 查询分区表, 不带分区字段

前提: 数据量足够大, 如果数据量比较少, 严格模式对此三项内容不生效
如何设置:
set hive.mapred.mode = strict;--开启严格模式
set hive.mapred.mode = nostrict; --开启非严格模式   最新默认
16、JVM 重用

此操作, 在hive2.x已经不必要设置了, 默认支持
jvm重用: 默认情况下, container资源容器只能使用一次,不能重复使用, 开启JVM重用, 运行container容器可以被重复使用,在hive2.x已经默认支持了
17、推测执行

Hadoop采用了推测执行(Speculative Execution)机制,它根据一定的法则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。
hadoop中默认两个阶段都开启了推测执行机制。
hive本身也提供了配置项来控制reduce-side的推测执行:

set hive.mapred.reduce.tasks.speculative.execution=true;

关于调优推测执行机制,还很难给一个具体的建议。如果用户对于运行时的偏差非常敏感的话,那么可以将这些功能关闭掉。如果用户因为输入数据量很大而需要执行长时间的map或者Reduce task的话,那么启动推测执行造成的浪费是非常巨大。

18、执行计划explain

使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。帮助我们了解底层原理,hive调优,排查数据倾斜等有很有帮助

使用示例:explain [...]sql查询语句;

explain sql语句: 查看执行计划的基本信息

https://img-blog.csdnimg.cn/direct/796f03c8c0104b76b7056d17ec18f8d8.png
(1)stage dependencies:各个stage之间的依赖性
包含多个stage阶段,例如 Stage-1和Stage-0,Stage-1 是根stage,Stage-0 依赖 Stage-1,
(2)stage plan:各个stage的执行计划
包含两部分: map端执行计划树和reduce端执行计划树
ks.speculative.execution=true;
关于调优推测执行机制,还很难给一个具体的建议。如果用户对于运行时的偏差非常敏感的话,那么可以将这些功能关闭掉。如果用户由于输入数据量很大而必要执行长时间的map或者Reduce task的话,那么启动推测执行造成的浪费是非常巨大。
## 18、执行计划explain使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。帮助我们了解底层原理,hive调优,排查数据倾斜等有很有帮助

使用示例:explain [...]sql查询语句;

explain sql语句: 查看执行计划的基本信息

[外链图片转存中…(img-33z4aUG4-1715785755032)]
(1)stage dependencies:各个stage之间的依赖性
包含多个stage阶段,例如 Stage-1和Stage-0,Stage-1 是根stage,Stage-0 依赖 Stage-1,
(2)stage plan:各个stage的执行计划
包含两部分: map端执行计划树和reduce端执行计划树
https://img-blog.csdnimg.cn/direct/786a79cdf4a941819e9ce3ccd0b414d8.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Hive 调优(包罗hive全部调优方式 看这一篇就够了)