hive性能优化模板
HiveSQLcount(distinct)效率问题及优化

HiveSQLcount(distinct)效率问题及优化上周拿到了我的第⼀个⼯作任务,统计⼀个按天分区每天都有百亿条数据条的hive表中account字段的⾮重⽤户数(⼤概两千万)。
后来⼜更改为按id字段分别统计每个id的⽤户数。
按照我数据库⽼师的教导,我很轻易的跳出来了count(distinct account)这个句⼦。
然后写上了⼀⾏查询,等待了四个⼩时,然后map反着跑就知道没这么容易的任务。
然后想起来Hive SQL 基于的mapreduce是并⾏计算,百亿的数据可不是平时测试时的mysql⾥的⼏百条数据。
这么想来应该是map和reduce的内存不够,set mapreduce.map.memory.mb=48192;set mapreduce.reduce.memory.mb=48192;执⾏语句select count(distinct account)from...where...继续mapreduce,三个⼩时后报错error in shuffle in fetcher#3. shuffle过程⼜出问题了。
找呀找,reducer只有1?那还怎么并⾏?果断set mapred.reduce.tasks=1000;⼜进⾏查询,发现reducer 还是1。
只能求助于万能的Internet了。
原来因为加⼊distinct,map阶段不能⽤combine消重,数据输出为(key,value)形式然后在reduce阶段进⾏消重。
重点是,Hive在处理COUNT这种“全聚合(full aggregates)”计算时,它会忽略⽤户指定的Reduce Task数,⽽强制使⽤1。
⽰意图如下解决办法:转换为⼦查询,转化为两个mapreduce任务先select distinct的字段,然后在count(),这样去重就会分发到不同的reduce块,count依旧是⼀个reduce但是只需要计数即可。
Hive优化

Hive优化1 概述1.1 Hive的特征1.可以通过SQL轻松访问数据的工具,从而实现数据仓库的任务,报告和数据分析等。
2.可以使已经存储的数据结构化。
3.可以直接访问存储在HDFS或者其他数据存储系统中的文件。
4.Hive除了支持MapReduce计算引擎之外还支持Spark和Tez这两种分布式计算引擎。
5.提供了类似sql查询语句的HiveSql对数据进行分析。
6.存储格式多样化。
1.2 Hive优势Hive的强大之处不是在与将数据转换成特定格式,而是利用Hadoop本身的InputFormat API来从不同的数据源中读取数据,然后使用OutputFormat API将数据写成不同的格式。
所以对于不同的数据源,或者写出不同的格式就需要不同的对应的InputFormat和OutputFormat类的实现。
Hive拥有统一的元数据管理,所以和spark,impala等SQL引擎通用。
(通用指的是拥有了统一的Metastore之后,在Hive中创建一张表,在spark/impala中能通用,反之在spark中创建一张表,在Hive中也是能用的)只需要共用元数据,就可以切换SQL引擎了。
Hive使用SQL语法,提供快速开发能力,还可以通过用户定义的函数,用户定义的聚合和用户定义的表函数进行扩展,避免了去写MapReduce,减少开发人员学习成本。
Hive中不仅可以使用逗号和制表符分隔文本文件。
还可以使用sequence File、RC、ORC、Parquet。
Hive指在最大限度的提高可伸缩性,性能,可扩展性,容错性以及与其输出格式的松散耦合。
数据离线处理:日志分析,海量数据结构化分析。
2 Hive函数Hive的SQL可以通过用户定义的函数,用户定义的聚合和用户定义的表函数进行扩展当Hive提供的内置函数无法满足你的业务需求时,此时就可以考虑使用用户自定义函数UDF(用户定义函数),UDAF(用户定义聚合函数),UDTF(用户定义表函数)的区别:▪udf 一进一出▪udaf 聚集函数,多进一出▪udtf 一进多出3 Hive优化3.1 慎用api大数据场景下不害怕数据量大,但是害怕数据倾斜。
Hive的10种优化总结

Hive的10种优化总结Hive作为⼤数据领域常⽤的数据仓库组件,在平时设计和查询时要特别注意效率。
影响Hive效率的⼏乎从不是数据量过⼤,⽽是数据倾斜、数据冗余、job或I/O过多、MapReduce分配不合理等等。
对Hive的调优既包含对HiveSQL语句本⾝的优化,也包含Hive配置项和MR⽅⾯的调整。
列裁剪和分区裁剪最基本的操作。
所谓列裁剪就是在查询时只读取需要的列,分区裁剪就是只读取需要的分区。
以我们的⽇历记录表为例:select uid,event_type,record_datafrom calendar_record_logwhere pt_date >= 20190201 and pt_date <= 20190224and status = 0;当列很多或者数据量很⼤时,如果select *或者不指定分区,全列扫描和全表扫描效率都很低。
Hive中与列裁剪优化相关的配置项是hive.optimize.cp,与分区裁剪优化相关的则是hive.optimize.pruner,默认都是true。
在HiveSQL解析阶段对应的则是ColumnPruner逻辑优化器。
谓词下推在关系型数据库如MySQL中,也有谓词下推(Predicate Pushdown,PPD)的概念。
它就是将SQL语句中的where谓词逻辑都尽可能提前执⾏,减少下游处理的数据量。
例如以下HiveSQL语句:select a.uid,a.event_type,b.topic_id,b.titlefrom calendar_record_log aleft outer join (select uid,topic_id,title from forum_topicwhere pt_date = 20190224 and length(content) >= 100) b on a.uid = b.uidwhere a.pt_date = 20190224 and status = 0;对forum_topic做过滤的where语句写在⼦查询内部,⽽不是外部。
大数据性能优化之Hive优化

大数据性能优化之Hive优化一、引言Hive是建立在Hadoop之上的数据仓库基础设施,用于处理大规模数据集。
然而,在处理大数据时,Hive的性能可能会受到一些因素的影响,如数据倾斜、查询优化等。
因此,本文将介绍一些Hive性能优化的方法,以提高查询效率和减少执行时间。
二、数据倾斜处理1. 了解数据倾斜的原因:数据倾斜是指在某些列或者分区中,数据的分布不均匀,导致某些任务的执行时间明显延长。
2. 使用随机数分桶:通过在表中添加一个随机数列,并使用该列进行分桶,可以将数据均匀分布到不同的桶中,从而减少数据倾斜的影响。
3. 使用动态分区:动态分区可以根据数据的值自动创建分区,避免了手动创建分区时可能浮现的数据倾斜问题。
三、查询优化1. 使用合适的数据存储格式:选择合适的存储格式可以提高查询性能。
例如,使用列式存储格式(如Parquet或者ORC)可以减少I/O操作,提高查询效率。
2. 使用分区和索引:通过将数据分成多个分区,并在常用的查询列上创建索引,可以减少扫描的数据量,提高查询速度。
3. 避免全表扫描:尽量避免使用SELECT *的方式查询数据,而是明确指定需要查询的列,减少不必要的数据读取。
4. 使用合适的连接方式:在Hive中,可以使用JOIN操作连接多个表。
为了提高查询性能,应尽量避免使用大表与大表的JOIN,可以考虑使用MAPJOIN或者BUCKET JOIN等方式来优化连接操作。
四、资源配置和调优1. 调整内存参数:根据集群的硬件资源和数据规模,合理配置Hive的内存参数,如mapreduce.map.memory.mb、mapreduce.reduce.memory.mb等,以充分利用集群资源。
2. 并行度调整:通过调整mapreduce.job.reduces参数,控制并行度,使得任务能够充分利用集群资源,提高数据处理速度。
3. 合理设置数据压缩:使用数据压缩可以减少磁盘占用和I/O操作,但过多的压缩会增加CPU负载。
hive优化总结

hive优化总结Hive是一个基于Hadoop的数据仓库基础设施工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的SQL查询功能。
然而,由于Hive处理大规模数据集时的复杂性,其性能可能不够理想。
因此,在实际应用中,我们需要对Hive进行优化,以提高其查询性能和效率。
首先,我们可以使用合适的存储格式来存储数据。
Hive支持多种存储格式,例如文本、Parquet和ORC。
对于大规模数据集,使用列式存储格式(如ORC)比行式存储格式(如文本)更高效。
列式存储格式可以减少I/O操作,提高查询性能。
其次,我们可以使用分区表和分桶表来优化查询。
分区表是将数据按照一定的规则分成多个分区存储的表,可以根据查询的条件只读取特定的分区,减少了不必要的数据读取和处理。
分桶表则是将数据分成多个桶存储,可以根据查询的条件只读取特定的桶,同样可以提高查询的效率。
另外,我们可以通过合理的数据压缩方式来减少存储空间,提高查询性能。
Hive支持多种数据压缩算法,如Snappy、LZO和Gzip。
选择合适的压缩算法可以在保证数据准确性的前提下减少存储空间,从而加快查询速度。
此外,我们还可以通过适当的索引使用来提高查询性能。
Hive 支持B树索引和位图索引。
B树索引适用于范围查询,而位图索引适用于离散值查询。
根据实际的查询场景,选择适合的索引类型可以加快查询速度。
另外,我们可以使用合适的硬件和网络配置来提高查询性能。
Hive的主要性能瓶颈包括CPU、内存和磁盘I/O。
通过增加硬件资源,如增加CPU核心数和内存容量,可以提高查询的并发能力和计算速度。
另外,优化网络传输的带宽和延迟也可以减少数据传输的时间,缩短查询的响应时间。
最后,我们可以使用MapReduce、Spark或Tez等并行计算框架来加快查询速度。
Hive支持多种执行引擎,可以根据具体的需求选择合适的执行引擎。
并行计算框架可以将查询任务并行化处理,并利用集群中的多台机器同时进行计算,从而加快查询速度。
Hive调优及优化的12种方式

Hive调优及优化的12种⽅式Hive调优及优化的12种⽅式请记住:在数据处理中,不怕数据量⼤,就怕数据倾斜!针对于Hive内部调优的⼀些⽅式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中的解决⽅案:在数据源头HDFS中控制⼩⽂件产⽣的个数,⽐如采⽤Sequencefile作为表存储格式,不要⽤textfile,在⼀定程度上可以减少⼩⽂件(常见于在流计算的时候采⽤Sequencefile格式进⾏存储)减少reduce的数量(可以使⽤参数进⾏控制)慎重使⽤动态分区,最好在分区中指定分区字段的val值最好数据的校验⼯作,⽐如通过脚本⽅式检测hive表的⽂件数量,并进⾏⽂件合并合并多个⽂件数据到⼀个⽂件中,重新构建表03.请慎重使⽤SELECT *原因:在⼤数据量多字段的数据表中,如果使⽤ SELECT * ⽅式去查询数据,会造成很多⽆效数据的处理,会占⽤程序资源,造成资源的浪费解决⽅案:在查询数据表时,指定所需的待查字段名,⽽⾮使⽤ * 号04.不要在表关联后⾯加WHERE条件原因:⽐如以下语句:SELECT * FROM stu as tLEFT JOIN course as t1ON t.id=t2.stu_idWHERE t.age=18;请思考上⾯语句是否具有优化的空间?如何优化?解决⽅案:采⽤谓词下推的技术,提早进⾏过滤有可能减少必须在数据库分区之间传递的数据量谓词下推的解释:所谓谓词下推就是通过嵌套的⽅式,将底层查询语句尽量推到数据底层去过滤,这样在上层应⽤中就可以使⽤更少的数据量来查询,这种SQL技巧被称为谓词下推(Predicate pushdown)那么上⾯语句就可以采⽤这种⽅式来处理:SELECT * FROM (SELECT * FROM stu WHERE age=18) as tLEFT JOIN course AS t1on t.id=t1.stu_id05.处理掉字段中带有空值的数据原因:⼀个表内有许多空值时会导致MapReduce过程中,空成为⼀个key值,对应的会有⼤量的value值, ⽽⼀个key的value会⼀起到达reduce造成内存不⾜解决⽅式:1、在查询的时候,过滤掉所有为NULL的数据,⽐如:create table res_tbl asselect n.* from(select * from res where id is not null ) nleft join org_tbl o on n.id = o.id;2、查询出空值并给其赋上随机数,避免了key值为空(数据倾斜中常⽤的⼀种技巧)create table res_tbl asselect n.* from res nfull join org_tbl o oncase when n.id is null then concat('hive', rand()) else n.id end = o.id;06.设置并⾏执⾏任务数通过设置参数 hive.exec.parallel 值为 true,就可以开启并发执⾏。
Hive优化

Hive常见优化一、数据倾斜1、什么是数据倾斜?Hadoop框架的特性决定最怕数据倾斜•由于数据分布不均匀,造成数据大量的集中到一点,造成数据热点。
节点间数据分布不均衡,会造成map端每个map任务的工作量不同,即map端数据倾斜。
Map-reduce,把相同key提交给同一个reduce,如果key不均衡就会造成不同的reduce的工作量不同。
以京东首页活动为例,曝光率大的是大活动,曝光率小的是小活动:假如reduce1处理的是小活动,reduce2处理大活动,reduce2干的活比其他reduce多很多,会出现其他reduce执行完毕了,reduce2还在缓慢执行。
症状:map阶段快,reduce阶段非常慢;某些map很快,某些map很慢;某些reduce很快,某些reduce奇慢。
如下情况:A、数据在节点上分布不均匀B、join时on关键词中个别值量很大(如null值)C、count(distinct),在数据量大的情况下,容易数据倾斜,因为count(distinct)是按group by字段分组,按distinct字段排序。
其中A无法避免。
B见后边的Join章节。
C语法上有时无法避免如何解决数据倾斜?实际上是没办法避免的,这里的解决只是个别情况起效:有数据倾斜的时候进行负载均衡set hive.groupby.skewindata=false;当选项设定为true,生成的查询计划会有两个MR Job。
第一个MR Job中,Map 的输出结果会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce中(这个过程可以保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操作。
Hive常用优化技巧

Hive常⽤优化技巧Hive优化最体现程序员的技术能⼒,⾯试官在⾯试时最喜欢问的就是Hive的优化技巧。
技巧1.控制reducer数量下⾯的内容是我们每次在hive命令⾏执⾏SQL时都会打印出来的内容:In order to change the average load for a reducer (in bytes):set hive.exec.reducers.bytes.per.reducer=<number>In order to limit the maximum number of reducers:set hive.exec.reducers.max=<number>In order to set a constant number of reducers:set mapreduce.job.reduces=<number>很多⼈都会有个疑问,上⾯的内容是⼲什么⽤的。
我们⼀⼀来解答,先看set hive.exec.reducers.bytes.per.reducer=<number>,这个⼀条Hive命令,⽤于设置在执⾏SQL的过程中每个reducer处理的最⼤字节数量。
可以在配置⽂件中设置,也可以由我们在命令⾏中直接设置。
如果处理的数据量⼤于number,就会多⽣成⼀个reudcer。
例如,number = 1024K,处理的数据是1M,就会⽣成10个reducer。
我们来验证下上⾯的说法是否正确:1. 执⾏set hive.exec.reducers.bytes.per.reducer=200000;命令,设置每个reducer处理的最⼤字节是200000。
2. 执⾏sql:select user_id,count(1) as cntfrom orders group by user_id limit 20;执⾏上⾯的sql时会在控制台打印出信息:Number of reduce tasks not specified. Estimated from input data size: 159In order to change the average load for a reducer (in bytes):set hive.exec.reducers.bytes.per.reducer=<number>In order to limit the maximum number of reducers:set hive.exec.reducers.max=<number>In order to set a constant number of reducers:set mapreduce.job.reduces=<number>Starting Job = job_1538917788450_0020, Tracking URL = http://hadoop-master:8088/proxy/application_1538917788450_0020/Kill Command = /usr/local/src/hadoop-2.6.1/bin/hadoop job -kill job_1538917788450_0020Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 159控制台打印的信息中第⼀句话:Number of reduce tasks not specified. Estimated from input data size: 159。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
优化时,把hive sql当做map reduce程序来读,会有意想不到的惊喜。
理解hadoop的核心能力,是hive优化的根本。
这是这一年来,项目组所有成员宝贵的经验总结。
长期观察hadoop处理数据的过程,有几个显著的特征:1.不怕数据多,就怕数据倾斜。
2.对jobs数比较多的作业运行效率相对比较低,比如即使有几百行的表,如果多次关联多次汇总,产生十几个jobs,没半小时是跑不完的。
map reduce作业初始化的时间是比较长的。
3.对sum,count来说,不存在数据倾斜问题。
4.对count(distinct ),效率较低,数据量一多,准出问题,如果是多count(distinct )效率更低。
优化可以从几个方面着手:1. 好的模型设计事半功倍。
2. 解决数据倾斜问题。
3. 减少job数。
4. 设置合理的map reduce的task数,能有效提升性能。
(比如,10w+级别的计算,用160个reduce,那是相当的浪费,1个足够)。
5. 自己动手写sql解决数据倾斜问题是个不错的选择。
set hive.groupby.skewindata=true;这是通用的算法优化,但算法优化总是漠视业务,习惯性提供通用的解决方法。
Etl开发人员更了解业务,更了解数据,所以通过业务逻辑解决倾斜的方法往往更精确,更有效。
6. 对count(distinct)采取漠视的方法,尤其数据大的时候很容易产生倾斜问题,不抱侥幸心理。
自己动手,丰衣足食。
7. 对小文件进行合并,是行至有效的提高调度效率的方法,假如我们的作业设置合理的文件数,对云梯的整体调度效率也会产生积极的影响。
8. 优化时把握整体,单个作业最优不如整体最优。
迁移和优化过程中的案例:问题1:如日志中,常会有信息丢失的问题,比如全网日志中的user_id,如果取其中的user_id和bmw_users关联,就会碰到数据倾斜的问题。
方法:解决数据倾斜问题解决方法1. User_id为空的不参与关联,例如:Select *From log aJoin bmw_users bOn er_id is not nullAnd er_id = er_idUnion allSelect *from log awhere er_id is null.解决方法2 :Select *from log aleft outer join bmw_users bon case when er_id is null then concat(‘dp_hive’,rand() ) else er_id end = er_id;总结:2比1效率更好,不但io少了,而且作业数也少了。
1方法log读取两次,jobs是2。
2方法job数是1 。
这个优化适合无效id(比如-99,’’,null等)产生的倾斜问题。
把空值的key 变成一个字符串加上随机数,就能把倾斜的数据分到不同的reduce上 ,解决数据倾斜问题。
因为空值不参与关联,即使分到不同的reduce上,也不影响最终的结果。
附上hadoop通用关联的实现方法(关联通过二次排序实现的,关联的列为parition key,关联的列c1和表的tag组成排序的group key,根据parition key分配reduce。
同一reduce内根据group key 排序)。
问题2:不同数据类型id的关联会产生数据倾斜问题。
一张表s8的日志,每个商品一条记录,要和商品表关联。
但关联却碰到倾斜的问题。
s8的日志中有字符串商品id,也有数字的商品id,类型是string的,但商品中的数字id是bigint的。
猜测问题的原因是把s8的商品id转成数字id做hash来分配reduce,所以字符串id的s8日志,都到一个reduce上了,解决的方法验证了这个猜测。
方法:把数字类型转换成字符串类型Select * from s8_log aLeft outer join r_auction_auctions bOn a.auction_id = cast(b.auction_id as string);问题3:利用hive 对UNION ALL的优化的特性hive对union all优化只局限于非嵌套查询。
比如以下的例子:select * from(select * from t1Group by c1,c2,c3Union allSelect * from t2Group by c1,c2,c3) t3Group by c1,c2,c3;从业务逻辑上说,子查询内的group by 怎么都看显得多余(功能上的多余,除非有count(distinct)),如果不是因为hive bug或者性能上的考量(曾经出现如果不子查询group by ,数据得不到正确的结果的hive bug)。
所以这个hive按经验转换成select * from(select * from t1Union allSelect * from t2) t3Group by c1,c2,c3;经过测试,并未出现union all的hive bug,数据是一致的。
mr的作业数有3减少到1。
t1相当于一个目录,t2相当于一个目录,那么对map reduce程序来说,t1,t2可以做为map reduce 作业的mutli inputs。
那么,这可以通过一个map reduce 来解决这个问题。
Hadoop 的计算框架,不怕数据多,就怕作业数多。
但如果换成是其他计算平台如oracle,那就不一定了,因为把大的输入拆成两个输入,分别排序汇总后merge(假如两个子排序是并行的话),是有可能性能更优的(比如希尔排序比冒泡排序的性能更优)。
问题4:比如推广效果表要和商品表关联,效果表中的auction id列既有商品id,也有数字id,和商品表关联得到商品的信息。
那么以下的hive sql性能会比较好Select * from effect aJoin (select auction_id as auction_id from auctionsUnion allSelect auction_string_id as auction_id from auctions) bOn a.auction_id = b.auction_id。
比分别过滤数字id,字符串id然后分别和商品表关联性能要好。
这样写的好处,1个MR作业,商品表只读取一次,推广效果表只读取一次。
把这个sql换成MR代码的话,map的时候,把a表的记录打上标签a,商品表记录每读取一条,打上标签b,变成两个<key ,value>对,<b,数字id>,<b,字符串id>。
所以商品表的hdfs读只会是一次。
问题5:先join生成临时表,在union all还是写嵌套查询,这是个问题。
比如以下例子:Select *From (select *From t1Uion allselect *From t4Union allSelect *From t2Join t3On t2.id = t3.id) xGroup by c1,c2;这个会有4个jobs。
假如先join生成临时表的话t5,然后union all,会变成2个jobs。
Insert overwrite table t5Select *From t2Join t3On t2.id = t3.id;Select * from (t1 union all t4 union all t5) ;hive在union all优化上可以做得更智能(把子查询当做临时表),这样可以减少开发人员的负担。
出现这个问题的原因应该是union all目前的优化只局限于非嵌套查询。
如果写MR程序这一点也不是问题,就是multi inputs。
问题6:使用map join解决数据倾斜的常景下小表关联大表的问题,但如果小表很大,怎么解决。
这个使用的频率非常高,但如果小表很大,大到map join会出现bug或异常,这时就需要特别的处理。
云瑞和玉玑提供了非常给力的解决方案。
以下例子:Select * from log aLeft outer join members bOn a.memberid = b.memberid.Members有600w+的记录,把members分发到所有的map上也是个不小的开销,而且map join不支持这么大的小表。
如果用普通的join,又会碰到数据倾斜的问题。
解决方法:Select /*+mapjoin(x)*/* from log aLeft outer join (select /*+mapjoin(c)*/d.*From (select distinct memberid from log ) cJoin members dOn c.memberid = d.memberid)xOn a.memberid = b.memberid。
先根据log取所有的memberid,然后mapjoin 关联members取今天有日志的members的信息,然后在和log做mapjoin。
假如,log里memberid有上百万个,这就又回到原来map join问题。
所幸,每日的会员uv 不会太多,有交易的会员不会太多,有点击的会员不会太多,有佣金的会员不会太多等等。
所以这个方法能解决很多场景下的数据倾斜问题。
问题7:HIVE下通用的数据倾斜解决方法,double被关联的相对较小的表,这个方法在mr 的程序里常用。
还是刚才的那个问题:Select * from log aLeft outer join (select /*+mapjoin(e)*/memberid, numberFrom members dJoin num e) bOn a.memberid= b.memberidAnd mod(a.pvtime,30)+1=b.number。
Num表只有一列number,有30行,是1,30的自然数序列。
就是把member表膨胀成30份,然后把log数据根据memberid和pvtime分到不同的reduce里去,这样可以保证每个reduce分配到的数据可以相对均匀。
就目前测试来看,使用mapjoin的方案性能稍好。
后面的方案适合在map join无法解决问题的情况下。
长远设想,把如下的优化方案做成通用的hive优化方法1. 采样log表,哪些memberid比较倾斜,得到一个结果表tmp1。
由于对计算框架来说,所有的数据过来,他都是不知道数据分布情况的,所以采样是并不可少的。
Stage12. 数据的分布符合社会学统计规则,贫富不均。