01 请慎重使用COUNT(DISTINCT col)
问题原因:
distinct会将b列所有的数据保存到内存中,形成一个类似hash的结构,速度是十分的块;但是在大数据背景下,因为b列所有的值都会形成以key值,极有可能发生OOM
解决方案:
所以,可以考虑使用Group By 或者 ROW_NUMBER() OVER(PARTITION BY col)方式代替COUNT(DISTINCT col)
02 小文件会造成资源的过度占用以及影响查询效率
问题原因:
众所周知,小文件在HDFS中存储本身就会占用过多的内存空间,那么对于MR查询过程中过多的小文件又会造成启动过多的Mapper Task, 每个Mapper都是一个后台线程,会占用JVM的空间
在Hive中,动态分区会造成在插入数据过程中,生成过多零碎的小文件(请回忆昨天讲的动态分区的逻辑)
不合理的Reducer Task数量的设置也会造成小文件的生成,因为最终Reducer是将数据落地到HDFS中的
Hive中分桶表的设置
解决方案:
在数据源头HDFS中控制小文件产生的个数,比如
采用Sequencefile作为表存储格式,不要用textfile,在一定程度上可以减少小文件(常见于在流计算的时候采用Sequencefile格式进行存储)
减少reduce的数量(可以使用参数进行控制)
慎重使用动态分区,最好在分区中指定分区字段的val值
最好数据的校验工作,比如通过脚本方式检测hive表的文件数量,并进行文件合并合并多个文件数据到一个文件中,重新构建表
03 请慎重使用SELECT(*)
问题原因:在大数据量多字段的数据表中,如果使用 SELECT * 方式去查询数据,会造成很多无效数据的处理,会占用程序资源,造成资源的浪费
解决方案:在查询数据表时,指定所需的待查字段名,而非使用 * 号
04 不要在表关联后面加WHERE条件
问题原因:比如以下语句:SELECT * FROM stu as t LEFT JOIN course as t1ON t.id=t2.stu_idWHERE t.age=18;请思考上面语句是否具有优化的空间?如何优化?解决方案:采用谓词下推的技术,提早进行过滤有可能减少必须在数据库分区之间传递的数据量谓词下推的解释:所谓谓词下推就是通过嵌套的方式,将底层查询语句尽量推到数据底层去过滤,这样在上层应用中就可以使用更少的数据量来查询,这种SQL技巧被称为谓词下推(Predicate pushdown) 那么上面语句就可以采用这种方式来处理:SELECT * FROM (SELECT * FROM stu WHERE age=18) as t LEFT JOIN course AS t1 on t.id=t1.stu_id05 处理掉字段中带有空值的数据
问题原因:一个表内有许多空值时会导致MapReduce过程中,空成为一个key值,对应的会有大量的value值, 而一个key的value会一起到达reduce造成内存不足解决方式:1、在查询的时候,过滤掉所有为NULL的数据,比如:create table res_tbl as select n.* from (select * from res where id is not null ) n left join org_tbl o on n.id = o.id;2、查询出空值并给其赋上随机数,避免了key值为空(数据倾斜中常用的一种技巧)create table res_tbl asselect n.* from res n full join org_tbl o on case when n.id is null then concat('hive', rand()) else n.id end = o.id06 处理掉字段中带有空值的数据
通过设置参数 hive.exec.parallel 值为 true,就可以开启并发执行。不过,在共享集群中,需要注意下,如果 job 中并行阶段增多,那么集群利用率就会增加。//打开任务并行执行07 设置合理的Reducer数量
08 JVM重用
09 为什么任务执行的时候只有一个reduce?
问题原因:
使用了Order by (Order By是会进行全局排序)
直接COUNT(1),没有加GROUP BY,比如:
有笛卡尔积操作
SELECT COUNT(1) FROM tbl WHERE pt=’202109’
解决方案:
避免使用全局排序,可以使用sort by进行局部排序
使用GROUP BY进行统计,不会进行全局排序,比如:
SELECT pt,COUNT(1) FROM tbl WHERE pt=’202109’group by pt;
10 选择使用Tez引擎
Tez: 是基于Hadoop Yarn之上的DAG(有向无环图,Directed Acyclic Graph)计算框架。它把Map/Reduce过程拆分成若干个子过程,同时可以把多个Map/Reduce任务组合成一个较大的DAG任务,减少了Map/Reduce之间的文件存储。同时合理组合其子过程,也可以减少任务的运行时间。
虽然现在最新版本的Hive默认其实支持的Tez引擎, 但是很多人或者大部分人往往还是希望用MR引擎,特别是在Tez报错,然后MR运行正常的时候
设置11 选择使用本地模式
有时候Hive处理的数据量非常小,那么在这种情况下,为查询出发执行任务的时间消耗可能会比实际job的执行时间要长,对于大多数这种情况,hive可以通过本地模式在单节点上处理所有任务,对于小数据量任务可以大大的缩短时间
12 选择使用严格模式
Hive提供了一种严格模式,可以防止用户执行那些可能产生意想不到的不好的影响查询比如:- END -