Fetch抓取机制(了解)
- 功能:在执行sql的时候,能不走MapReduce程序处理就尽量不走MapReduce程序处理。
- 尽量直接去操作数据文件。
- 设置: hive.fetch.task.conversion= more。 默认设置
css
--在下述4种情况下 sql不走mr程序
-- more 模式下如下内容不需要走mr程序
--全局查找
select * from student;
--字段查找
select num,name from student;
--limit 查找
select num,name from student limit 2;
-- 简单的条件过滤
select num,name from student where num > 2;
-- minimal 模式下如下内容不需要走mr程序
--全局查找
select * from student;
--字段查找
select num,name from student;
--limit 查找
select num,name from student limit 2;
-- none 模式下所有的操作都需要走mr程序
mapreduce本地模式 (了解)
-
功能:如果非要执行MapReduce程序,能够本地执行的,尽量不提交yarn上执行。
-
默认是关闭的。意味着只要走MapReduce就提交yarn执行。
-
mapreduce.framework.name = local 本地模式 mapreduce.framework.name = yarn 集群模式set hive.exec.mode.local.auto = true;
--3个条件必须都满足 自动切换本地模式
The total input size of the job is lower than: hive.exec.mode.local.auto.inputbytes.max (128MB by default) --数据量小于128M
The total number of map-tasks is less than: hive.exec.mode.local.auto.tasks.max (4 by default) --maptask个数少于4个
The total number of reduce tasks required is 1 or 0. --reducetask个数是0 或
知识点3 : join优化 (重要)
- 底层还是MapReduce的join优化。
- MapReduce中有两种join方式。指的是join的行为发生什么阶段。
- map端join
- reduce端join
- 优化1:Hive自动尝试选择map端也进行join提高join的效率
- 这个优化策略在大表和小表的连接过程中使用(在map端join尽量不在reduce端join)
bash
开启 mapjoin 参数设置:
(1)设置自动选择 mapjoin
set hive.auto.convert.join = true; --默认为 true
(2)大表小表的阈值设置:
set hive.mapjoin.smalltable.filesize= 25000000;
- 优化2:桶表join提高优化效率。bucket mapjoin 大表 join 中表
bash
1.1 条件
1) set hive.optimize.bucketmapjoin = true;
2) 一个表的bucket数是另一个表bucket数的整数倍 第一个表分为4桶,第二个表可以是 1桶 2桶 4桶 8桶...
3) bucket列 == join列
4) 必须是应用在map join的场景中
1.2 注意
1)如果表不是bucket的,只是做普通join。
优化3:大表join大表(key值打散,连接过滤条件提前)
bash
--背景:
大表join大表本身数据就十分具体,如果join字段存在null空值 如何处理它?
任何数据和null进行连接,都无法连接成功,所以此时我们会进行空值处理
--方式1:空key的过滤 此行数据不重要 where is not null
参与join之前 先把空key的数据过滤掉
SELECT a.* FROM (SELECT * FROM nullidtable WHERE id IS NOT NULL ) a JOIN ori b ON a.id =b.id;
--方式2:空Key转换
CASE WHEN a.id IS NULL THEN 'xxx任意字符串' ELSE a.id END -- 如果给空值赋值默认值空值数量太大,会造成某个桶的数据量过大
CASE WHEN a.id = 'xxx' THEN concat('hive', rand()) ELSE a.id --避免转换之后数据倾斜 随机分布打散
-- 方式3: 对于两张大表中的数据先过滤再连接
-- 不建议
select * from t1 join t2 on t1.id = t2.id and t1.price > 1000;
-- 建议
select * from (select * from t1 where price > 1000) t1 join t2 on t1.id = t2.id;
知识点4 : 列裁剪和分区裁剪 (重要且简单)
- 列裁剪(在列式存储中效果最明显)
只读取我们指定的列,其余列不查看 列裁剪,提高查询效率,减小检索范围分区裁剪
bash
Hive在读数据的时候,可以只读取查询中所需要用到的列,而忽略其他列。例如,若有以下查询:
在实施此项查询中,Q表有5列(a,b,c,d,e),Hive只读取查询逻辑中真实需要的3列a、b、e, 而忽略列c,d;这样做节省了读取开销,中间表存储开销和数据整合开销。
注意:Hive自动执行这种裁剪优化
裁剪对应的参数项为:
--默认值为真 在hive 2.x中无需在配置了, 直接为固定值: true
hive.optimize.cp=true;
- 分区裁剪
只读取我们指定的分区数据,其余分区不查看,提高查询效率,减小检索范围
在join中必须书写on 尽量不要使用where 如果一定要使用在连接之前使用where
bash
执行查询SQL的时候, 能在join之前提前过滤的操作, 一定要提前过滤, 不要在join后进行过滤操作
如果操作的表是一张分区表, 那么建议一定要带上分区字段, 以减少扫描的数据量, 从而提升效率,
例如,若有以下查询:
select * from t1 join t2 on t1.id = t2.id and t1.dt = '2021-12-31'; (dt是分区字段)
select * from (select * from t1 where dt = '2021-12-31') t1 join t2 on t1.id = t2.id;
注意:Hive自动执行这种裁剪优化
分区参数为:
-- 默认为就是true (在hive 2.x中无需在配置了, 直接为固定值: true)
hive.optimize.pruner=true
知识点5 : group by 数据倾斜优化(了解)
- 数据倾斜 : 我们开启map任务时会将同一个key的数据读取到一个map任务中,如果有一个key里边的数据量过大,而其他的key 数据量极少此时就会出现数据倾斜
bash
开启Map端聚合参数设置
--(1)是否在Map端进行聚合,默认为True
set hive.map.aggr = true;
--(2)在Map端进行聚合操作的条目数目
set hive.groupby.mapaggr.checkinterval = 100000;
--(3)有数据倾斜的时候进行负载均衡(默认是false)
set hive.groupby.skewindata = true;
--Q:在hive中数据倾斜开启负载均衡之后 底层执行机制是什么样?
--step1:启动一个MapReduce程序 将倾斜的数据随机发送到各个reduce中 进行打散 负载均衡
每个reduce进行聚合都是局部聚合
--step2:再启动第二个MapReduce程序 将上一步局部聚合的结果汇总起来进行最终的聚合
