Hive sql优化
### Hive SQL优化技巧详解 #### 一、数据倾斜优化 数据倾斜是指在Hive查询过程中,数据不均匀地分布在不同的Reducer上,导致某些Reducer处理的数据量远大于其他Reducer,从而影响整个查询性能的问题。解决数据倾斜的方法主要有以下几种: 1. **JOIN数据倾斜** - **JOIN原则**:在进行JOIN操作时,应该将较小的表放置在JOIN操作符的左边,因为Hive在执行JOIN时会尝试将左侧表的内容加载到内存中,将小表放在左边有助于减少内存溢出的风险。 - **MapJoin**:对于较小的表,可以使用MapJoin技术,在Map阶段完成JOIN操作,避免数据倾斜问题。MapJoin需要满足条件:参与JOIN的小表可以在Map阶段被完全读入内存中。实现方式通常通过SQL提示`/*+ MAPJOIN(表名) */`指定。 ```sql INSERT OVERWRITE TABLE phone_traffic SELECT /*+MAPJOIN(phone_location)*/ l.phone, p.location, l.traffic FROM phone_location p JOIN log l ON (p.phone = l.phone); ``` 相关参数配置: - `hive.join.emit.interval`:控制JOIN操作的间隔,默认为1000。 - `hive.mapjoin.size.key`:用于MapJoin操作的键的最大数量,默认为10000。 - `hive.mapjoin.cache.numrows`:缓存中小表的最大行数,默认为10000。 2. **GROUP BY 数据倾斜** - **Map端部分聚合**:为了减轻数据倾斜的影响,可以通过在Map端进行部分聚合操作来降低Reduce端的压力。这需要设置参数`hive.map.aggr=true`开启此功能,并且通过`hive.groupby.mapaggr.checkinterval`来控制在Map端进行聚合操作的条目数目。 - **负载均衡**:当存在数据倾斜时,可以启用`hive.groupby.skewindata=true`来实现负载均衡。这样,第一个MRJob会随机分配数据给各个Reducer,进行部分聚合;第二个MRJob则根据预处理后的数据完成最终的聚合操作。 3. **COUNT DISTINCT 数据倾斜** - 使用`COUNT(DISTINCT)`函数时,所有涉及的数据都会被发送到同一个Reducer上,可能导致数据倾斜。一种解决方案是将`COUNT(DISTINCT)`转换为基于`GROUP BY`的操作,以减少Reducer上的数据量。 例如: ```sql SELECT COUNT(*) FROM ( SELECT user_id FROM dm_user WHERE ds='20150701' GROUP BY user_id ) t; ``` #### 二、合理控制Map与Reduce数量 1. **合并Map文件,减少Map数量** - 当存在大量小文件时,可以合并这些文件以减少Map任务的数量,提高效率。可以通过设置参数来实现: - `mapred.max.split.size`:最大split大小。 - `mapred.min.split.size.per.node`:单节点最小split大小。 - `mapred.min.split.size.per.rack`:单机架最小split大小。 - `hive.input.format`:设置为CombineHiveInputFormat,以便支持合并文件。 2. **拆分Map文件,增加Map数量** - 对于较大的文件或复杂的任务,可以通过拆分文件来增加Map数量,从而提高处理速度。例如,通过`DISTRIBUTE BY`语句随机分配记录到多个文件中。 3. **调整Reduce个数** - 可以通过调整`hive.exec.reducers.bytes.per.reducer`参数来控制Reduce任务的数量。例如,设置为500MB,意味着每500MB数据会产生一个Reduce任务。 通过以上方法和技术的应用,可以有效地优化Hive查询性能,减少数据倾斜带来的负面影响,提高大数据处理的速度和效率。