Fectch 抓取是指对某些状况下的查询没必要使用 MapReduce 计算node
将 hive.fetch.task.conversion 设置成 more,在全局查找、字段查找、limit查找等都不走 MapReduce 数据库
多数的 Hadoop Job 是须要 Hadoop 提供的完整的可扩展性来处理大数据集的,不过,有时 Hive 的输入数据量是很是小的,在这种状况下,为查询触发执行任务消耗的时间可能会比实际job的执行时间要多的多,对于大多数这种状况,Hive 能够经过本地模式在单台机器上处理全部的任务,对于小数据集,执行时间能够明显被缩短apache
将 hive.exec.mode.local.auto 设置成 true,让 Hive 在适当的时候自动启动这个优化并发
有时 JOIN 超时是由于某些 KEY 对应的数据太多,而相同 KEY 对应的数据都会发送到相同的 Reducer 上,从而致使内存不够,此时咱们应该仔细分不少状况下,这些 KEY 对应的数据是异常数据,咱们须要在 SQL 语句中进行过滤。负载均衡
有时虽然某个 KEY 为空对应的数据不少,可是相应的数据不是异常数据,必需要包含在 JOIN 的结果中,此时咱们能够将表中 KEY 为空的字段赋一个随机的值,使得数据随机均匀地分不到不一样的 Reducer 上。jvm
若是不指定 MapJOIN 或者不符合 MapJOIN 的条件,那么 Hive 解析器会将 JOIN 转换成 Common JOIN,即:在Reduce阶段完成 JOIN,容易发生数据倾斜,能够用 MapJOIN 把小表加载到内存在 Map 端进行 JOIN,避 Reducer 处理。ide
默认状况下,Map阶段同一Key数据分发给一个reduce,当一个key数据过大时就倾斜了oop
# 是否在Map端进行聚合 set hive.map.aggr = true # 在Map端进行聚合操做的条目数目 set hive.groupby.mapaggr.checkinterval = 100000 # 有数据倾斜的时候进行负载均衡 set hive.groupby.skewindata = true
当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果会随机分布到 Reduce 中,每一个 Reduce 作部分聚合操做,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不一样的 Reduce中,从而达到负载均衡的目的,第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce中(这个过程能够保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操做性能
数据量小的时候无所谓,数据量大的状况下,因为 COUNT DISTINCT 的全聚合操做,即便设定了 Reduce Task 个数,Hive 也只会启动一个Reduce,这就形成一个 Reduce 处理的数据量太大,致使整个 Job 很难完成,通常 COUNT DISTINCT 使用先 GROUP BY 再 COUNT 的方式替换fetch
不使用笛卡尔积
禁止使用 SELECT *
对分区表Insert数据时候,数据库自动会根据分区字段的值,将数据插入到相应的分区中,即动态分区
# 开启动态分区功能 hive.exec.dynamic.partition=true # 设置为非严格模式 hive.exec.dynamic.partition.mode=nonstrict # 在全部执行MR的节点上,最大一共能够建立多少个动态分区,默认1000 hive.exec.max.dynamic.partitions=1000 # 在每一个执行MR的节点上,最大能够建立多少个动态分区,该参数须要根据实际的数据来设定 hive.exec.max.dynamic.partitions.pernode=100 # 整个MR Job中,最大能够建立多少个HDFS文件,默认100000 hive.exec.max.created.files=100000 # 当有空分区生成时,是否抛出异常。通常不须要设置 hive.error.on.empty.partition=false
当 input 的文件都很大,任务逻辑复杂,Map 执行很是慢的时候,能够考虑增长 Map 数,来使得每一个 Map 处理的数据量减小,从而提升任务的执行效率
在 Map 执行前合并小文件,减小 Map 数:
set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
在 Map-Reduce 的任务结束时合并小文件的设置
# 在 map-only 任务结束时合并小文件 SET hive.merge.mapfiles = true; # 在Map-Reduce任务结束时合并小文件 SET hive.merge.mapredfiles = true; # 合并文件的大小,默认256M SET hive.merge.size.per.task = 268435456; # 当输出文件的平均大小小于该值时,启动一个独立的Map-Reduce任务进行文件merge SET hive.merge.smallfiles.avgsize = 16777216;
# 每一个Reduce处理的数据量默认是256MB hive.exec.reducers.bytes.per.reducer=256000000 # 每一个任务最大的Reduce数,默认为1009 hive.exec.reducers.max=1009 # 计算Reduce数的公式 N=min(hive.exec.reducers.max, 数据总量/hive.exec.reducers.bytes.per.reducer)
Hive 会将一个查询转化成一个或者多个阶段,这样的阶段能够是 MapReduce 阶段、抽样阶段、合并阶段、limit 阶段,或者 Hive 执行过程当中可能须要的其余阶段,默认状况下,Hive 一次只会执行一个阶段,不过,某个特定的 job 可能包含众多的阶段,而这些阶段可能并不是彻底互相依赖的,也就是说有些阶段是能够并行执行的,这样可能使得整个 job 的执行时间缩短。不过,若是有更多的阶段能够并行执行,那么 job 可能就越快完成。
经过设置参数 hive.exec.parallel 值为 true,就能够开启并发执行。不过,在共享集群中,须要注意下,若是 job 中并行阶段增多,那么集群利用率就会增长。
Hive 提供了一个严格模式,能够防止用户执行那些可能意想不到的很差的影响的查询
开启严格模式须要修改 hive.mapred.mode 值为 strict,开启严格模式能够禁止 种类型的查询:
JVM 重用是 Hadoop 调优参数的内容,其对 Hive 的性能具备很是大的影响,特别是对于很难避免小文件的场景或 task 特别多的场景,这类场景大多数执行时间都很短。
Hadoop 的默认配置一般是使用派生来执行和任务的,这时的启动过程可能会形成至关大的开销,尤为是执行的包含有成百上千任务的状况。
重用可使得实例在同一个中从新使用屡次。
须要在 Hadoop 的 mapred-site.xml 中配置,可是有个缺点是重用次数过大,会产生大量的垃圾
<property> <name>mapreduce.job.jvm.numtasks</name> <value>10</value> <description>How many tasks to run per jvm. If set to -1, there is no limit. </description> </property>
若是用户由于输入数据量很大而须要执行长时间的 Map 或者 Reduce Task 的话,那么启动推测执行形成的浪费是很是巨大大