登 录
注 册
< 大 数 据
Flink
Hadoop
Spark
Hive
HBase
Kafka
其他框架
生产中常见问题
Hive压缩和存储
通过JDBC访问
企业级调优(一)
企业级调优(二)
企业级调优(三)
UDF实战
Hive调优参数大全
热门推荐>>>
中台架构
中台建设与架构
Hadoop
源码分析-NN启动(三)
HBase
HBased对接Hive
Linux
Nginx高可用
Python
数据导出工具
Flink
3分钟搭建Flink SQL测试环境
Kafka
Kafka对接Flume
深度学习
卷积神经网络
数据结构与算法
选择合适的算法
MySQL
数据备份恢复
计算机系统
信号量同步线程
其他框架
Azkaban Flow1.0与2.0
ClickHouse
表引擎-其他类型
技术成长
最好的职业建议
精选书单
技术成长书单—机器学习
技术资讯
数据在线:计算将成为公共服务
开发工具
IntelliJ IDEA 20年发展回顾(二)
系统工具
Mac命令行工具
虚拟化
内存虚拟化概述
云原生
云原生构建现代化应用
云服务
一文搞懂公有云、私有云...
Java
Spring Boot依赖注入与Runners
Go
Go函数与方法
SQL
SQL模板
安全常识
一文读懂SSO
当前位置:
首页
>>
Hive
>>
企业级调优(二)
企业级调优(二)
2020-10-08 16:08:38 星期四 阅读:1396
####Count(Distince)去重 数据量小的时候无所谓,数据量大的情况下,由于count distinct操作需要一个reduce task来完成,这个reduce需要处理的数据量太大,就会导致整个Job很难完成,甚至造成OOM。一般count distinct操作都会先使用group by 再count的方式进行替换。 ``` # 直接count(distinct)方式查询 select count(distinct uid) from order_info # 改用group by的方式 select count(A.*) from (select uid from order_info group by uid) A ``` ####笛卡尔积 hive可以开启笛卡尔积检查 ####行列过滤 行:在select中,只拿需要的列,如果有,尽量使用分区过滤,少使用select * 列:在分区裁剪中,当使用外关联时,如果将副表的过滤条件写在where后面,那么就会先全表关联后再过滤 ``` # 先全表关联,再where select t1.id , t2.id from t1 join t2 on t1.id = b.id where t2.id <=10 # 先where再关联,把关联的数据量控制到最小再去关联 select from t1 join (select id from t2 where t2.id <= 10 ) t3 on t1.id = t3.id ``` ####动态分区 Hive对分区表进行插入的时候,支持按照某个字段的值来进行动态分区。需要设置如下参数 ``` # 开启hive动态分区(默认是开启的) hive> set hive.exec.dynamic.partition=true; # 设置非严格模式(如果是严格模式,则必须指定至少一个分区为静态分区 # 非严格模式允许所有的分区字段都可以使用动态分区 hive> set hive.exec.dynamic.partition.mode=nostrict # 所有执行MR的节点上,最大一共可以创建多个动态分区 hive> set hive.exec.dynamic.partitions=1000 # 在每个执行的MR节点上,最大可以创建多少个动态分区。 # 该参数需要根据具体的分区字段有多少枚举值来确定,如果枚举值为100,但是该参数设置为50 # 万一某个任务的map阶段涉及到70个枚举值,则会读不到另外20个枚举值而报错 hive> set hive.exec.max.dynamic.partitions.pernode=100 # 整个MR Job中,最大可以创建多少个HDFS文件 hive> set hive.exec.max.created.files=100000 # 当有空分区的时候是否抛出异常(也就是在插入数据的时候,分区字段的值是空的,是否抛出异常) # 默认应该就是false hive> set hive.error.on.empty.partition=false ``` 创建动态分区表(创建方式跟静态分区没区别) ``` # 创建一个根据city字段分区的分区表 create table table_tmp( id int, name string ) partitioned by (city string) row format delimited fields terminated by "01" stored by textfile ``` 往动态分区的表里插入数据,要保证插入数据时各个字段的顺序,最后一个字段的值会被视为动态分区的条件。如果插入的时候最后一个字段不是city,而是name,也是可以执行插入的, 但是生成的动态分区的值就是按照name字段进行分区的。 ``` # 插入的时候指定分区字段,但是不需要指定插入到哪个分区 insert into table table_tmp partition(city) select id , name , city from table_comon ``` ####合理设置reduce数 ``` # 设置reduce的个数 hive> set mapreduce.job.reduces=15; # 每个reduce是处理的数据(默认是256MB) hive> set hive.exec.reducers.bytes.per.reducer=256000000 # 每个任务最大的reduce数,模拟认为1009 hive> set hive.exec.reducers.max=1009 ``` reduce的个数并不是越多越好,启动和初始化reduce也会消耗时间和资源;还有一点,有多个reduce就会有多个输出文件,如果生成了很多小文件,那么这些小文件如果作为下一个任务的输入,则也会出现小文件过多的问题。 所以设置reduce数的时候需要考虑:大数据量设置合适的reduce数,使得单个reduce任务处理数据量大小要合适。 ####严格模式 ``` hive> set hive.mapred.mode=strict ``` 或者永久修改 ``` <property> <name>hive.mapred.mode</name> <value>strict</value> </property> ``` 严格模式下不被允许的操作有如下几种 笛卡尔积 不指定分区 bigint和string数据类型进行比较 bigint和doubles数据类型进行比较 order by 的时候没有写limit语句 ####查看执行计划 可以查看需要执行的任务相关执行计划,可以理解为翻译需要执行的SQL的语法树。包括数据的输入输出用到的列和文件等。 `hive> explain select * from tablename;`