当前位置: 首页 > news >正文

Hive调优集锦(2)

3.8 Join 优化

Join优化整体原则:

1、优先过滤后再进行 join 操作,最大限度的减少参与 join 的数据量
2、小表 join 大表,最好启动 mapjoin,hive 自动启用 mapjoin, 小表不能超过25M,可以更改
3、Join on的条件相同的话,最好放入同一个job,并且 join 表的排列顺序从小到大:
select a., b., c.*
from a join b
on a.id = b.id
join c
on a.id = c.i
4、如果多张表做 join, 如果多个链接条件都相同,会转换成一个JOb

• 优先过滤数据

尽量减少每个阶段的数据量,对于分区表能用上分区字段的尽量使用,同时只选择后面需要使用到的列,最大限度的减少参与 Join 的数据量。

• 小表 join 大表原则

小表 join 大表的时应遵守小表 join 大表原则,原因是 join 操作的 reduce 阶段,位于 join 左边的表内容会被加载进内存,将条目少的表放在左边,可以有效减少发生内存溢出的几率。join 中执行顺序是从左到右生成 Job,应该保证连续查询中的表的大小从左到右是依次增加的。

• 使用相同的连接键

在 hive 中,当对 3 个或更多张表进行 join 时,如果 on 条件使用相同字段,那么它们会合并为一个 MapReduce Job,利用这种特性,可以将相同的 join on 放入一个 job 来节省执行时间。

• 尽量原子操作

尽量避免一个SQL包含复杂的逻辑,可以使用中间表来完成复杂的逻辑。

• 大表 Join 大表

1、 空 key 过滤:有时 join 超时是因为某些 key 对应的数据太多,而相同key 对应的数据都会发送到相同的 reducer 上,从而导致内存不够。此时我们应该仔细分析这些异常的 key,很多情况下,这些 key 对应的数据是异常数据,我们需要在SQL语句中进行过滤。
2、 空 key 转换:有时虽然某个 key 为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在 join 的结果中,此时我们可以表a中 key 为空的字段赋一个随机的值,使得数据随机均匀地分不到不同的 reducer 上。

3.9 启用 MapJoin

这个优化措施,但凡能用就用! 大表 join 小表 小表满足需求: 小表数据小于控制条件时。

MapJoin 是将 join 双方比较小的表直接分发到各个 map 进程的内存中,在 map 进程中进行 join 操作,这样就不用进行 reduce 步骤,从而提高了速度。只有 join 操作才能启用 MapJoin。

## 是否根据输入小表的大小,自动将reduce端的common join 转化为map join,将小表刷入内存中。
## 对应逻辑优化器是MapJoinProcessor
set hive.auto.convert.join = true;
## 刷入内存表的大小(字节)
set hive.mapjoin.smalltable.filesize = 25000000;
## hive会基于表的size自动的将普通join转换成mapjoin
set hive.auto.convert.join.noconditionaltask=true;
## 多大的表可以自动触发放到内层LocalTask中,默认大小10M
set hive.auto.convert.join.noconditionaltask.size=10000000;

Hive 可以进行多表 Join。Join 操作尤其是 Join 大表的时候代价是非常大的。MapJoin 特别适合大小表join的情况。
在Hive join场景中,一般总有一张相对小的表和一张相对大的表,小表叫 build table,大表叫 probe table。
Hive 在解析带 join 的 SQL 语句时,会默认将最后一个表作为 probe table,将前面的表作为 build table 并试图将它们读进内存。
如果表顺序写反,probe table 在前面,引发 OOM 的风险就高了。
在维度建模数据仓库中,事实表就是 probe table,维度表就是 build table。
这种 Join 方式在 map 端直接完成 join 过程,消灭了 reduce,效率很高。而且 MapJoin 还支持非等值连接。
当 Hive 执行 Join 时,需要选择哪个表被流式传输(stream),哪个表被缓存(cache)。
Hive 将JOIN 语句中的最后一个表用于流式传输,因此我们需要确保这个流表在两者之间是最大的。
如果要在不同的 key 上 join 更多的表,那么对于每个 join 集,只需在 ON 条件右侧指定较大的表。
也可以手动开启 mapjoin:

--SQL方式,在SQL语句中添加MapJoin标记(mapjoin hint)
--将小表放到内存中,省去shffle操作
// 在没有开启mapjoin的情况下,执行的是reduceJoin
SELECT /*+ MAPJOIN(smallTable) */ smallTable.key, bigTable.value FROM
smallTable JOIN bigTable ON smallTable.key = bigTable.key;
/*+mapjoin(smalltable)*/

• Sort-Merge-Bucket(SMB) Map Join

它是另一种 Hive Join 优化技术,使用这个技术的前提是所有的表都必须是分桶表(bucket)和分桶排序的(sort)。分桶表的优化!

具体实现:

1、针对参与 join 的这两张做相同的 hash 散列,每个桶里面的数据还要排序
2、这两张表的分桶个数要成倍数。
3、开启 SMB join 的开关!

一些常见参数设置:

## 当用户执行bucket map join的时候,发现不能执行时,禁止查询
set hive.enforce.sortmergebucketmapjoin=false;
## 如果join的表通过sort merge join的条件,join是否会自动转换为sort merge join
set hive.auto.convert.sortmerge.join=true;
## 当两个分桶表 join 时,如果 join on的是分桶字段,小表的分桶数是大表的倍数时,可以启用mapjoin 来提高效率。
# bucket map join优化,默认值是 false
set hive.optimize.bucketmapjoin=false;
## bucket map join 优化,默认值是 false
set hive.optimize.bucketmapjoin.sortedmerge=false;

3.10 Join数据倾斜优化

在编写 Join 查询语句时,如果确定是由于 join 出现的数据倾斜,那么请做如下设置:

# join的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置
set hive.skewjoin.key=100000;
# 如果是join过程出现倾斜应该设置为true
set hive.optimize.skewjoin=false;

如果开启了,在 Join 过程中 Hive 会将计数超过阈值 hive.skewjoin.key(默认100000)的倾斜 key 对应的行临时写进文件中,然后再启动另一个 job 做 map join 生成结果。
通过 hive.skewjoin.mapjoin.map.tasks 参数还可以控制第二个 job 的 mapper 数量,默认10000。

set hive.skewjoin.mapjoin.map.tasks=10000

3.11 CBO 优化

join 的时候表的顺序的关系:前面的表都会被加载到内存中。后面的表进行磁盘扫描。

select a., b., c.* 
from a 
join b on a.id = b.id 
join c on a.id = c.id;

Hive 自 0.14.0 开始,加入了一项 “Cost based Optimizer” 来对 HQL 执行计划进行优化,这个功能通过 “hive.cbo.enable” 来开启。
在 Hive 1.1.0 之后,这个 feature 是默认开启的,它可以 自动优化 HQL 中多个 Join 的顺序,并选择合适的 Join 算法。
CBO,成本优化器,代价最小的执行计划就是最好的执行计划。
传统的数据库,成本优化器做出最优化的执行计划是依据统计信息来计算的,Hive 的成本优化器也一样。
Hive 在提供最终执行前,优化每个查询的执行逻辑和物理执行计划。
这些优化工作是交给底层来完成的。
根据查询成本执行进一步的优化,从而产生潜在的不同决策:如何排序连接,执行哪种类型的连接,并行度等等。要使用基于成本的优化(也称为CBO),请在查询开始设置以下参数:

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;

3.12 怎样做笛卡尔积

当 Hive 设定为严格模式(hive.mapred.mode=strict)时,不允许在 HQL 语句中出现笛卡尔积,这实际说明了 Hive 对笛卡尔积支持较弱。因为找不到 Join key,Hive 只能使用 1 个 reducer 来完成笛卡尔积。
当然也可以使用 limit 的办法来减少某个表参与 join 的数据量,但对于需要笛卡尔积语义的需求来说,经常是一个大表和一个小表的 Join 操作,结果仍然很大(以至于无法用单机处理),这时 MapJoin 才是最好的解决办法。MapJoin,顾名思义,会在 Map 端完成 Join 操作。这需要将 Join 操作的一个或多个表完全读入内存。
PS:MapJoin 在子查询中可能出现未知 BUG。在大表和小表做笛卡尔积时,规避笛卡尔积的方法是,给 Join 添加一个 Join key,原理很简单:将小表扩充一列 join key,并将小表的条目复制数倍,join key 各不相同;将大表扩充一列 join key 为随机数。
精髓就在于复制几倍,最后就有几个 reduce 来做,而且大表的数据是前面小表扩张 key 值范围里面随机出来的,所以复制了几倍 n,就相当于这个随机范围就有多大 n,那么相应的,大表的数据就被随机的分为了 n 份。并且最后处理所用的 reduce 数量也是 n,而且也不会出现数据倾斜。

3.13 Group By 优化

默认情况下,Map 阶段同一个 Key 的数据会分发到一个 Reduce 上,当一个 Key 的数据过大时会产生数据倾斜。进行 group by 操作时可以从以下两个方面进行优化。
Map 端部分聚合
事实上并不是所有的聚合操作都需要在 Reduce 部分进行,很多聚合操作都可以先在 Map 端进行部分聚合,然后在 Reduce 端的得出最终结果。

## 开启Map端聚合参数设置
set hive.map.aggr=true;
# 设置map端预聚合的行数阈值,超过该值就会分拆job,默认值100000
set hive.groupby.mapaggr.checkinterval=100000

有数据倾斜时进行负载均衡
当 HQL 语句使用 group by 时数据出现倾斜时,如果该变量设置为 true,那么 Hive 会自动进行负载均衡。
策略就是把 MapReduce 任务拆分成两个:第一个先做预汇总,第二个再做最终汇总。

# 自动优化,有数据倾斜的时候进行负载均衡(默认是false)
set hive.groupby.skewindata=false;

当选项设定为 true 时,生成的查询计划有两个 MapReduce 任务。

1、在第一个 MapReduce 任务中,map 的输出结果会随机分布到 reduce 中,每个 reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 group by key 有可能分发到不同的 reduce 中,从而达到负载均衡的目的;
2、第二个 MapReduce 任务再根据预处理的数据结果按照 group by key 分布到各个 reduce 中,最后完成最终的聚合操作

Map 端部分聚合:并不是所有的聚合操作都需要在 Reduce 端完成,很多聚合操作都可以先在 Map 端进行部分聚合,最后在 Reduce 端得出最终结果,对应的优化器为 GroupByOptimizer。
那么如何用 group by 方式同时统计多个列?

select t.a, sum(t.b), count(t.c), count(t.d) from some_table t group by t.a;

下面是解决方法:

select t.a, sum(t.b), count(t.c), count(t.d) from (select a, b, null c,null d from some_tableunion allselect a,0 b, c,null d    from some_table group by a,cunion allselect a,0 b,null c,d    from some_table group by a,d
) t;

3.14 Order By 优化

order by 只能是在一个 reduce 进程中进行,所以如果对一个大数据集进行 order by ,会导致一个reduce 进程中处理的数据相当大,造成查询执行缓慢。

1、在最终结果上进行order by,不要在中间的大数据集上进行排序。如果最终结果较少,可以在一个reduce上进行排序时,那么就在最后的结果集上进行order by。
2、如果是取排序后的前N条数据,可以使用distribute by和sort by在各个reduce上进行排序后前N条,然后再对各个reduce的结果集合合并后在一个reduce中全局排序,再取前N条,因为参与全局排序的order by的数据量最多是reduce个数 * N,所以执行效率会有很大提升。

在 Hive 中,关于数据排序,提供了四种语法,一定要区分这四种排序的使用方式和适用场景。

1、order by:全局排序,缺陷是只能使用一个reduce
2、sort by:单机排序,单个reduce结果有序
3、cluster by:对同一字段分桶并排序,不能和sort by 连用
4、distribute by + sort by:分桶,保证同一字段值只存在一个结果文件当中,结合 sort by 保证每个 reduceTask 结果有序

Hive HQL 中的 order by 与其他 SQL 方言中的功能一样,就是将结果按某字段全局排序,这会导致所有 map 端数据都进入一个 reducer 中,在数据量大时可能会长时间计算不完。
如果使用 sort by,那么还是会视情况启动多个 reducer 进行排序,并且保证每个 reducer 内局部有序。
为了控制map 端数据分配到 reducer 的 key,往往还要配合 distribute by 一同使用。
如果不加distribute by 的话,map 端数据就会随机分配到 reducer。
提供一种方式实现全局排序:两种方式:

1、建表导入数据准备

create table if not exists student(id int, name string, sex string, age int,department string) row format delimited fields terminated by ",";
load data local inpath "/home/bigdata/students.txt" into table student;

2、第一种方式

-- 直接使用order by来做。如果结果数据量很大,这个任务的执行效率会非常低
select id,name,age from student order by age desc limit 3;

3、第二种方式

-- 使用distribute by + sort by 多个reduceTask,每个reduceTask分别有序
set mapreduce.job.reduces=3;
drop table student_orderby_result;
-- 范围分桶 0 < 18 < 1 < 20 < 2
create table student_orderby_result as select * from student distribute by (case
when age > 20 then 0 when age < 18 then 2 else 1 end) sort by (age desc)

关于分界值的确定,使用采样的方式,来估计数据分布规律。

3.15 Count Distinct优化

当要统计某一列去重数时,如果数据量很大,count(distinct) 就会非常慢,原因与 order by 类似,count(distinct) 逻辑只会有很少的 reducer 来处理。
这时可以用 group by 来改写:

-- 先 group by 在 count
select count(1) from (select age from studentwhere department >= "MA"group by age
) t;

再来一个例子:
优化前 ,一个普通的只使用一个reduceTask来进行count(distinct) 操作。

-- 优化前(只有一个reduce,先去重再count负担比较大):
select count(distinct id) from tablename;

优化后 ,但是这样写会启动两个 MR job(单纯 distinct 只会启动一个),所以要确保数据量大到启动 job 的 overhead 远小于计算耗时,才考虑这种方法。
当数据集很小或者 key 的倾斜比较明显时,group by 还可能会比 distinct 慢。

-- 优化后(启动两个job,一个job负责子查询(可以有多个reduce),另一个job负责count(1)):
select count(1) from (select distinct id from tablename) tmp;
select count(1) from (select id from tablename group by id) tmp; // 推荐使用这种

3.16 怎样写 in/exists 语句

在Hive的早期版本中,in/exists语法是不被支持的,但是从 hive-0.8x 以后就开始支持这个语法。但是不推荐使用这个语法。虽然经过测验,Hive-2.3.6 也支持 in/exists 操作,但还是推荐使用 Hive 的一个高效替代方案:left semi join 。

比如说:

-- in / exists 实现
select a.id, a.name from a where a.id in (select b.id from b);
select a.id, a.name from a where exists (select id from b where a.id = b.id);

可以使用 join 来改写:

select a.id, a.name from a join b on a.id = b.id;

应该转换成:

-- left semi join 实现
select a.id, a.name from a left semi join b on a.id = b.id;

3.17 使用 vectorization 技术

在计算类似 scan, filter, aggregation 的时候, vectorization 技术以设置批处理的增量大小为 1024 行单次来达到比单条记录单次获得更高的效率。

set hive.vectorized.execution.enabled=true ;
set h/ive.vectorized.execution.reduce.enabled=true;

3.18 多重模式

如果你碰到一堆SQL,并且这一堆SQL的模式还一样。都是从同一个表进行扫描,做不同的逻辑。
有可优化的地方:如果有 n 条SQL,每个SQL执行都会扫描一次这张表
如果一个 HQL 底层要执行 10 个 Job,那么能优化成 8 个一般来说,肯定能有所提高,多重插入就是一个非常实用的技能。一次读取,多次插入,有些场景是从一张表读取数据后,要多次利用,这时可以使用 multi insert 语法。

from sale_detailinsert overwrite table sale_detail_multi partition (sale_date='2019',region='china' )select shop_name, customer_id, total_price where .....insert overwrite table sale_detail_multi partition (sale_date='2020',region='china' )select shop_name, customer_id, total_price where .....;

说明:multi insert 语法有一些限制。

1、一般情况下,单个SQL中最多可以写128路输出,超过128路,则报语法错误。
2、在一个multi insert中:对于分区表,同一个目标分区不允许出现多次。对于未分区表,该表不能出现多次。
3、对于同一张分区表的不同分区,不能同时有insert overwrite和insert into操作,否则报错返回。

Multi-Group by 是 Hive 的一个非常好的特性,它使得 Hive 中利用中间结果变得非常方便。例如

FROM (SELECT a.status, b.school, b.gender FROM status_updates a JOIN profiles b ON (a.userid = b.userid and a.ds='2019-03-20' )) subq1INSERT OVERWRITE TABLE gender_summary PARTITION(ds='2019-03-20')SELECT subq1.gender, COUNT(1) GROUP BY subq1.genderINSERT OVERWRITE TABLE school_summary PARTITION(ds='2019-03-20')SELECT subq1.school, COUNT(1) GROUP BY subq1.school;

上述查询语句使用了 Multi-Group by 特性连续 group by 了 2 次数据,使用不同的 Multi-Group by。
这一特性可以减少一次 MapReduce 操作。

3.19 启动中间结果压缩

map 输出压缩

set mapreduce.map.output.compress=true;
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;

中间数据压缩
中间数据压缩就是对 hive 查询的多个 Job 之间的数据进行压缩。最好是选择一个节省CPU耗时的压缩方式。
可以采用 snappy 压缩算法,该算法的压缩和解压效率都非常高。

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

结果数据压缩
最终的结果数据(Reducer输出数据)也是可以进行压缩的,可以选择一个压缩效果比较好的,可以减少数据的大小和数据的磁盘读写时间。
注:常用的 gzip,snappy 压缩算法是不支持并行处理的,如果数据源是 gzip/snappy压缩文件大文件,这样只会有有个 mapper 来处理这个文件,会严重影响查询效率。
所以如果结果数据需要作为其他查询任务的数据源,可以选择支持 splitable 的 LZO 算法,这样既能对结果文件进行压缩,还可以并行的处理,这样就可以大大的提高 job 执行的速度了。

set hive.exec.compress.output=true;
set mapreduce.output.fileoutputformat.compress=true;
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.LzoCodec;
set mapreduce.output.fileoutputformat.compress.type=BLOCK;

四、Hive 架构层面

4.1 启用本地抓取
Hive 的某些 SQL 语句需要转换成 MapReduce 的操作,某些 SQL 语句就不需要转换成 MapReduce 操作,但是同学们需要注意,理论上来说,所有的 SQL 语句都需要转换成 MapReduce 操作,只不过Hive 在转换 SQL 语句的过程中会做部分优化,使某些简单的操作不再需要转换成 MapReduce,例如:

1、只是 select * 的时候
2、where 条件针对分区字段进行筛选过滤时
3、带有 limit 分支语句时

Hive 从 HDFS 中读取数据,有两种方式:启用MapReduce读取 和 直接抓取。
直接抓取数据比 MapReduce 方式读取数据要快的多,但是只有少数操作可以使用直接抓取方式。
可以通过 hive.fetch.task.conversion 参数来配置在什么情况下采用直接抓取方式:

minimal:只有 select * 、在分区字段上 where 过滤、有 limit 这三种场景下才启用直接抓取方式。
more:在 select、where 筛选、limit 时,都启用直接抓取方式。

查看 Hive 的抓取策略:

## 查看
set hive.fetch.task.conversion;

设置Hive的抓取策略:

## 默认more
set hive.fetch.task.conversion=more;

请看 hive-default.xml 中关于这个参数的解释:

<property><name>hive.fetch.task.conversion</name><value>more</value>
<description>Expects one of [none, minimal, more].Some select queries can be converted to single FETCH task minimizing latency.Currently the query should be single sourced not having any subquery and should not haveany aggregations or distincts (which incurs RS), lateral views and joins.0. none : disable hive.fetch.task.conversion1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only2. more : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
</description>
</property>
<property><name>hive.fetch.task.conversion.threshold</name><value>1073741824</value>
<description>Input threshold for applying hive.fetch.task.conversion. If target table is native, input length is calculated by summation of file lengths. If it's not native, storage handler for the table can optionally implementorg.apache.hadoop.hive.ql.metadata.InputEstimator interface.
</description>
</property>

4.2 本地执行优化

Hive 在集群上查询时,默认是在集群上多台机器上运行,需要多个机器进行协调运行,这种方式很好的解决了大数据量的查询问题。但是在 Hive 查询处理的数据量比较小的时候,其实没有必要启动分布式模式去执行,因为以分布式方式执行设计到跨网络传输、多节点协调等,并且消耗资源。对于小数据集,可以通过本地模式,在单台机器上处理所有任务,执行时间明显被缩短。
启动本地模式涉及到三个参数:

## 打开hive自动判断是否启动本地模式的开关
set hive.exec.mode.local.auto=true;
## map任务数最大值,不启用本地模式的task最大个数
set hive.exec.mode.local.auto.input.files.max=4;
## map输入文件最大大小,不启动本地模式的最大输入文件大小
set hive.exec.mode.local.auto.inputbytes.max=134217728;

4.3 JVM重用

Hive 语句最终会转换为一系列的 MapReduce 任务,每一个MapReduce 任务是由一系列的 MapTask和 ReduceTask 组成的,默认情况下,MapReduce 中一个 MapTask 或者 ReduceTask 就会启动一个JVM 进程,一个 Task 执行完毕后,JVM 进程就会退出。这样如果任务花费时间很短,又要多次启动JVM 的情况下,JVM 的启动时间会变成一个比较大的消耗,这时,可以通过重用 JVM 来解决。

set mapred.job.reuse.jvm.num.tasks=5;

JVM也是有缺点的,开启JVM重用会一直占用使用到的 task 的插槽,以便进行重用,直到任务完成后才会释放。
如果某个 不平衡的job 中有几个 reduce task 执行的时间要比其他的 reduce task 消耗的时间要多得多的话,那么保留的插槽就会一直空闲却无法被其他的 job 使用,直到所有的 task 都结束了才会释放。
根据经验,一般来说可以使用一个 cpu core 启动一个 JVM,假如服务器有 16 个 cpu core ,但是这个节点,可能会启动 32 个mapTask,完全可以考虑:启动一个JVM,执行两个Task 。

4.4 并行执行

有的查询语句,Hive 会将其转化为一个或多个阶段,包括:MapReduce 阶段、抽样阶段、合并阶段、limit 阶段等。默认情况下,一次只执行一个阶段。但是,如果某些阶段不是互相依赖,是可以并行执行的。多阶段并行是比较耗系统资源的。
一个 Hive SQL 语句可能会转为多个 MapReduce Job,每一个 job 就是一个 stage,这些 Job 顺序执行,这个在 cli 的运行日志中也可以看到。但是有时候这些任务之间并不是是相互依赖的,如果集群资源允许的话,可以让多个并不相互依赖 stage 并发执行,这样就节约了时间,提高了执行速度,但是如果集群资源匮乏时,启用并行化反倒是会导致各个 Job 相互抢占资源而导致整体执行性能的下降。
启用并行化:

## 可以开启并发执行。
set hive.exec.parallel=true;
## 同一个sql允许最大并行度,默认为8。
set hive.exec.parallel.thread.number=16;

4.5 推测执行

在分布式集群环境下,因为程序Bug(包括Hadoop本身的bug),负载不均衡或者资源分布不均等原因,会造成同一个作业的多个任务之间运行速度不一致,有些任务的运行速度可能明显慢于其他任务(比如一个作业的某个任务进度只有50%,而其他所有任务已经运行完毕),则这些任务会拖慢作业的整体执行进度。

为了避免这种情况发生,Hadoop采用了推测执行(Speculative Execution)机制,它根据一定的法则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。

# 启动mapper阶段的推测执行机制
set mapreduce.map.speculative=true;
# 启动reducer阶段的推测执行机制
set mapreduce.reduce.speculative=true;

建议

如果用户对于运行时的偏差非常敏感的话,那么可以将这些功能关闭掉。如果用户因为输入数据量很大而需要执行长时间的MapTask或者ReduceTask的话,那么启动推测执行造成的浪费是非常巨大大。
设置开启推测执行参数:Hadoop 的 mapred-site.xml 文件中进行配置。

<property><name>mapreduce.map.speculative</name><value>true</value><description>If true, then multiple instances of some map tasks may be executed in parallel.</description>
</property>
<property><name>mapreduce.reduce.speculative</name><value>true</value><description>If true, then multiple instances of some reduce tasks may be executed in parallel.</description>
</property>

Hive 本身也提供了配置项来控制 reduce-side 的推测执行。

<property><name>hive.mapred.reduce.tasks.speculative.execution</name><value>true</value><description>Whether speculative execution for reducers should be turned on. </description>
</property>

4.6 Hive严格模式

所谓严格模式,就是强制不允许用户执行有风险的 HiveQL 语句,一旦执行会直接失败。
但是Hive中为了提高SQL语句的执行效率,可以设置严格模式,充分利用Hive的某些特点。

## 设置Hive的严格模式
set hive.mapred.mode=strict;
set hive.exec.dynamic.partition.mode=nostrict;

注意:当设置严格模式之后,会有如下限制:

1、对于分区表,必须添加where对于分区字段的条件过滤
select * from student_ptn where age > 25
2、order by语句必须包含limit输出限制
select * from student order by age limit 100;
3、限制执行笛卡尔积的查询
select a.*, b.* from a, b;
4、在hive的动态分区模式下,如果为严格模式,则必须需要一个分区列式静态分区

其他参考优化

hive性能优化小结(1)

hive性能优化小结(2)

hive优化器(2)上

hive优化器(2)下

相关文章:

Hive调优集锦(2)

3.8 Join 优化 Join优化整体原则&#xff1a; 1、优先过滤后再进行 join 操作&#xff0c;最大限度的减少参与 join 的数据量 2、小表 join 大表&#xff0c;最好启动 mapjoin&#xff0c;hive 自动启用 mapjoin, 小表不能超过25M&#xff0c;可以更改 3、Join on的条件相同的…...

一文谈谈Git

"And if forever lasts till now Alright" 为什么要有git&#xff1f; 想象一下&#xff0c;现如今你的老师同时叫你和张三&#xff0c;各自写一份下半年的学习计划交给他。 可是你的老师是一个极其"较真"的人&#xff0c;发现你俩写的学习计划太"水&…...

嵌入式数据库之SQLite

1.SQLite简介 轻量化&#xff0c;易用的嵌入式数据库&#xff0c;用于设备端的数据管理&#xff0c;可以理解成单点的数据库。传统服务器型数据 库用于管理多端设备&#xff0c;更加复杂。 SQLite是一个无服务器的数据库&#xff0c;是自包含的。这也称为嵌入式数据库&#x…...

idea下tomcat运行乱码问题解决方法

idea虚拟机选项添加-Dfile.encodingUTF-8...

人工智能TensorFlow MNIST手写数字识别——实战篇

上期文章TensorFlow手写数字-训练篇,我们训练了我们的神经网络,本期使用上次训练的模型,来识别手写数字(本期构建TensorFlow神经网络代码为上期文章分享代码) http://scs.ryerson.ca/~aharley/vis/conv/ 0、插入第三方库 from PIL import Image# 处理图片 import tensorf…...

Vue 本地应用-计数器

逻辑是在点击按钮的时候执行&#xff0c;那么要为按钮绑定点击事件&#xff0c;整体语法如下&#xff1a; <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>首页</title><link href"" type"text/c…...

深入了解HTTP代理在网络爬虫与SEO实践中的角色

随着互联网的不断发展&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;成为各大企业和网站重要的推广手段。然而&#xff0c;传统的SEO方法已经难以应对日益复杂和智能化的搜索引擎算法。在这样的背景下&#xff0c;HTTP代理爬虫作为一种重要的工具&#xff0c;正在逐渐被…...

使用docker搭建nacos

使用docker搭建nacos docker搭建最新版nacosMySQL下简历nacos配置数据表拉取镜像创建挂载目录启动容器访问nacos docker搭建nacos 2.0版本 docker搭建最新版nacos 最近想在自己服务器上搭建一个nacos服务&#xff0c;以前一直在本地的windows上使用&#xff0c;而且使用着naco…...

flask中的常用装饰器

flask中的常用装饰器 Flask 框架中提供了一些内置的装饰器&#xff0c;这些装饰器可以帮助我们更方便地开发 Web 应用。以下是一些常用的 Flask 装饰器&#xff1a; app.route()&#xff1a;这可能是 Flask 中最常用的装饰器。它用于将 URL 路由绑定到一个 Python 函数&#x…...

SQL基础语法 | 增删改查、分组、排序、limit

Shell命令框和Navicat联合使用 一、数据库层面 创建数据库 postgres# CREATE DATABASE runoobdb;查看数据库 postgres# \l选择数据库 postgres# \c runoobdb删除数据库 postgres# DROP DATABASE runoobdb;二、表格层面 创建表格 CREATE TABLE table_name(字段名称 字段数据类型…...

QT: 用定时器完成闹钟的实现

闹钟项目&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> #include <QTime> #include <QDebug> #include <QTextToSpeech> #include <QMessageBox> #include <QTimer>QT_BEGIN…...

Boyer-Moore 投票算法

这里先贴题目&#xff1a; Boyer-Moore 投票算法&#xff1a; 通俗点来讲&#xff0c;就是占领据点&#xff0c;像攻城那样&#xff0c;对消。 当你的据点有人时对消&#xff0c;无人时就占领。 这道题使用该算法可实现时间复杂度为O(n),空间复杂度为O(1)&#xff0c;接下来看…...

C# 翻转二叉树

226 翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#xff1a;…...

RocketMQ教程-(5)-功能特性-消费者分类

Apache RocketMQ 支持 PushConsumer 、 SimpleConsumer 以及 PullConsumer 这三种类型的消费者&#xff0c;本文分别从使用方式、实现原理、可靠性重试和适用场景等方面为您介绍这三种类型的消费者。 背景信息​ Apache RocketMQ 面向不同的业务场景提供了不同消费者类型&…...

Kafka原理剖析

一、简介 Kafka是一个分布式的、分区的、多副本的消息发布-订阅系统&#xff0c;它提供了类似于JMS的特性&#xff0c;但在设计上完全不同&#xff0c;它具有消息持久化、高吞吐、分布式、多客户端支持、实时等特性&#xff0c;适用于离线和在线的消息消费&#xff0c;如常规的…...

word怎么转换成pdf?分享几种转换方法

word怎么转换成pdf&#xff1f;将Word文档转换成PDF文件有几个好处。首先&#xff0c;PDF文件通常比Word文档更容易在不同设备和操作系统上查看和共享。其次&#xff0c;PDF文件通常比Word文档更难以修改&#xff0c;这使得它们在需要保护文件内容的情况下更加安全可靠。最后&a…...

基于XDMA 中断模式的 PCIE3.0 QT上位机与FPGA数据交互架构 提供工程源码和QT上位机源码

目录 1、前言2、我已有的PCIE方案3、PCIE理论4、总体设计思路和方案图像产生、发送、缓存数据处理XDMA简介XDMA中断模式图像读取、输出、显示QT上位机及其源码 5、vivado工程详解6、上板调试验证7、福利&#xff1a;工程代码的获取 1、前言 PCIE&#xff08;PCI Express&#…...

Vue 中通用的 css 列表入场动画效果

css 代码 .gradientAnimation {animation-name: gradient;animation-duration: 0.85s;animation-fill-mode: forwards;opacity: 0; }/* 不带前缀的放到最后 */ keyframes gradient {0% {opacity: 0;transform: translate(-100px, 0px);}100% {opacity: 1;transform: translate…...

微分流形2:流形上的矢量场和张量场

来了来了&#xff0c;切向量&#xff0c;切空间。流形上的所有的线性泛函的集合&#xff0c;注意是函数的集合。然后取流形上的某点p&#xff0c;它的切向量为&#xff0c;线性泛函到实数的映射。没错&#xff0c;是函数到实数的映射&#xff0c;是不是想到了求导。我们要逐渐熟…...

C++数组、向量和列表的练习

运行代码&#xff1a; //C数组、向量和列表的练习 #include"std_lib_facilities.h"int main() try {int ii[10] { 0,1,2,3,4,5,6,7,8,9 };for (int i 0; i < 10; i)//把数组中的每个元素值加2ii[i] 2;vector<int>vv(10);for (int i 0; i < 10; i)vv…...

视频剪辑矩阵分发系统Unable to load FFProbe报错技术处理?

问题一 报错处理 对于视频剪辑矩阵分发系统中出现的“Unable to load FFProbe”报错问题&#xff0c;可以采取以下技术处理措施进行解决。 1.检查系统中是否正确安装了FFProbe工具&#xff0c;并确保其路径正确配置。 2.检查系统环境变量是否正确设置&#xff0c;包括FFPr…...

Docker轻量级可视化工具Portainer

Portainer是一个轻量级的管理UI界面&#xff0c;用于管理Docker容器、镜像、卷和网络。它支持端口映射、容器启动、停止、删除、日志查看等功能&#xff0c;同时也提供了可视化的监控和统计功能&#xff0c;可以快速轻松的管理多个Docker主机。Portainer不需要额外安装依赖&…...

功率放大器在电光调制中的应用有哪些

电光调制是一种利用光电效应将电信号转化为光信号的技术。在实现电光调制的过程中&#xff0c;功率放大器作为一个重要的组件&#xff0c;具有对输入电信号进行放大和控制的功能。本文将介绍功率放大器的基本原理、特点以及在电光调制中的应用。 基本原理 功率放大器是一种能够…...

MyBatis入门程序

1.MyBatis 入门程序开发步骤 SqlSession&#xff1a;代表Java程序和数据库之间的会话。&#xff08;HttpSession是Java程序和浏览器之间的会话&#xff09; SqlSessionFactory&#xff1a;是“生产”SqlSession的“工厂”。 工厂模式&#xff1a;如果创建某一个对象&#xff…...

C++快速切换 头文件和源文件

有没有一种快速的方法 &#xff0c; 将头文件中的声明 直接在源文件中自动写出来&#xff0c; 毕竟头文件中已经有声明了&#xff0c; 我只需要写具体实现就行了&#xff0c;没有必要把声明的部分再敲一遍在 Visual Studio 中&#xff0c;你可以使用快速生成函数定义的功能来实…...

对原型、原型链的理解

在 JavaScript 中是使用构造两数来新建一个对象的&#xff0c;每一个构造函数的内部都有一个 prototype 属性&#xff0c;它的属性值是一个对象&#xff0c;这个对象包含了可以由该构造西数的所有实例共享的属性和方法。当使用构造函数新建一个对象后&#xff0c;在这个对象的内…...

7月26日,每日信息差

1、日本经产省将讨论让消费者负担核电站重启费。若被采用&#xff0c;那么即便是与把源自可再生能源作为卖点的新电力公司签约的消费者&#xff0c;也将负担重启核电站的费用 2、国家发改委&#xff1a;电厂存煤和出力均达历史同期最高水平 3、国家深改委&#xff1a;全国统调…...

git修改已经push后的commit注释

回到倒数第8次提交 git rebase -i HEAD~8修改注释&#xff0c;然后把最前面的pick改成edit 修改注释 git commit --amendrebase确认 git rebase --continue强制提交 git push -f origin master参考&#xff1a;https://blog.csdn.net/qq_16942727/article/details/1260355…...

网络云存储服务器,数据库服务器|PetaExpress

云存储服务器是什么&#xff1f; 云存储服务器是一种在线存储(英语:Cloud storage&#xff09;该模式是将数据存储在通常由第三方托管的多个虚拟服务器上&#xff0c;而不是独家服务器上。 云存储服务器有几种结构 架构方法分为两类&#xff1a;一类是通过服务进行架构&…...

java语法基础--基本数据类型

一、数据类型概括 1、整数类型 2、浮点型 3、布尔类型 4、字符类型 二、数据类型的使用 1、整数类型的使用 超出类型范围 //1.1 定义一个byte类型的变量&#xff0c;并且设置它超过byte类型范围// 如果定义的数值在byte类型范围内&#xff0c;那么就能正常使用&#xff0c;//…...