Hive个人笔记

一.数据倾斜

    在计算数据的时候,数据的分散度不够,导致大量的数据集中到了一台或者几台机器上计算,这些数据的计算速度远远低于平均计算速度,导致整个计算过程过慢。


  如何解决

       订单场景,某一天在北京和上海两个城市多了强力的推广,结果可能是这两个城市的订单量增长了10000%,其余城市的数据量不变。然后我们要统计不同城市的订单情况,这样,一做group操作,可能直接就数据倾斜了。

解决数据倾斜有这几个思路:

1.业务逻辑,上面的例子,我们单独对这两个城市来做count,最后和其它城市做整合。

2.程序层面,Hive中,经常遇到count(distinct)操作,这样会导致最终只有一个reduce,可以先group 再在外面包一层count。

3.调参方面,Hadoop和Spark都自带了很多的参数和机制来调节数据倾斜,合理利用它们就能解决大部分问题。

                  set hive.exec.reducers.max=200;

                  set mapred.reduce.tasks= 200;---增大Reduce个数

                  set hive.groupby.mapaggr.checkinterval=100000 ;--group的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置

                  set hive.groupby.skewindata=true; --如果是group by过程出现倾斜 应该设置为true

                  set hive.skewjoin.key=100000; --这个是join的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置

                  set hive.optimize.skewjoin=true;--如果是join 过程出现倾斜 应该设置为true


   从业务和数据上解决数据倾斜 :

有损的方法:

找到异常数据,比如ip为0的数据,过滤掉

无损的方法:

对分布不均匀的数据,单独计算

先对key做一层hash,先将数据打散让它的并行度变大,再汇集

数据预处理

二.常用函数

1.FIRST_VALUE

   取分组内排序后,截止到当前行,第一个值

2.LAST_VALUE

   取分组内排序后,截止到当前行,最后一个值

      用法:

       first_value(testtype) over (partition by device_id order by create_time desc) as testtype

3.lateral view explode

   lateral view用于和split、explode等UDTF一起使用的,能将一行数据拆分成多行数据,在此基础上可以对拆分的数据进行聚合,lateral view首先为原始表的每行调用UDTF,UDTF会把一行拆分     成一行或者多行,lateral view在把结果组合,产生一个支持别名表的虚拟表。

A                         B                                C

190     [1030,1031,1032,1033,1190]      select id

191     [1030,1031,1032,1033,1190]      select id

希望的结果是:

190    1030  select id 

190    1031  select id

190    1032  select id 

190    1033  select id

190    1190  select id

191    1030  select id

191    1031  select id

191    1032  select id 

191    1033  select id

191    1190  select id

select A,B,C from table_1 LATERAL VIEW explode(B) table1 as B得到上述结果

4.字符串连接函数:concat 

   语法: concat(string A, string B…)

   返回值: string

   说明:返回输入字符串连接后的结果,支持任意个输入字符串

举例: 

   hive> select concat(‘abc’,'def’,'gh’) from lxw_dual;

   abcdefgh

5.带分隔符字符串连接函数:concat_ws

   语法: concat_ws(string SEP, string A, string B…)  

   返回值: string  

   说明:返回输入字符串连接后的结果,SEP表示各个字符串间的分隔符  

   举例:  

    hive> select concat_ws(‘,’,'abc’,'def’,'gh’) from dual;  

   abc,def,gh  

6.collect_max

语法:FUNC(x,val,n)其中n是要返回的值的数量,val为double类型。

   说明:Similar to collect, but save only the keys containing the max 20 values. 

   举例 :collect_max(coalesce(receiver_mobile, ''), cast(mobile_cnt as double), 3)

     返回三个 map

7.map_keys

   语法:map_keys(Map)

   返回值:Returns an unordered array containing the keys of the input map.

   说明:

   举例:map_keys(collect_max(coalesce(receiver_mobile, ''), cast(mobile_cnt as double), 3))

8.map_values

   语法:map_values(Map)

   返回值:Returns an unordered array containing the values of the input map.

   说明:

9.unix_timestamp

   获取当前UNIX时间戳函数: unix_timestamp

   语法:   unix_timestamp()

返回值:   bigint 

说明: 获得当前时区的UNIX时间戳 

   举例:

 hive>   select unix_timestamp() from dual;

1323309615 

   日期转UNIX时间戳函数: unix_timestamp

   语法:   unix_timestamp(string date)

返回值:   bigint 

   说明: 转换格式为“yyyy-MM-dd HH:mm:ss“的日期到UNIX时间戳。如果转化失败,则返回0。

   举例:

hive>   select unix_timestamp(’2011-12-07 13:01:03′) from dual; 

   1323234063

   指定格式日期转UNIX时间戳函数: unix_timestamp

   语法:   unix_timestamp(string date, string pattern)

   返回值:   bigint

   说明: 转换pattern格式的日期到UNIX时间戳。如果转化失败,则返回0。

   举例:

   hive>   select unix_timestamp(’20111207 13:01:03′,’yyyyMMdd HH:mm:ss’) from dual;

   1323234063

9.lag,lead

lag 和lead 可以 获取结果集中,按一定排序所排列的当前行的上下相邻若干offset 的某个行的某个列(不用结果集的自关联);lag ,lead 分别是向前,向后

语法:LAG(col,n,DEFAULT) 

说明:用于统计窗口内往上第n行值,第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往上第n行为NULL时候,取默认值,如不指定,则为NULL)

    返回值:见说明

    举例:

HIve> select *  from kkk;                                                                                                  

        ID NAME                                                   

---------- --------------------                                   

         1 1name                                                  

         2 2name                                                  

         3 3name                                                  

         4 4name                                                  

         5 5name                                                                                                             

HIve> select id,name,lag(name,1,0) over ( order by id )  from kkk;                                                            

        ID NAME                 LAG(NAME,1,0)OVER(ORDERBYID)      

---------- -------------------- ----------------------------      

         1 1name                0                                 

         2 2name                1name                             

         3 3name                2name                             

         4 4name                3name                             

         5 5name                4name                                                                                               

HIve> select id,name,lead(name,2,0) over ( order by id )  from kkk;                                                             

        ID NAME                 LEAD(NAME,2,0)OVER(ORDERBYID)     

---------- -------------------- -----------------------------     

         1 1name                3name                             

         2 2name                4name                             

         3 3name                5name                             

         4 4name                0                          

         5 5name                0                                                                                     

10.GROUPING SETS

        GROUPING SETS会把在单个GROUP BY逻辑中没有参与GROUP BY的那一列置为NULL值,使它成为常量占位列。这样聚合出来的结果,未被GROUP BY的列将显示为NULL。但是数据表中很可能原来存在NULL值,所以会有歧义,为了解决这个歧义问题,可以使用HQL提供的一个Grouping__ID函数,这个函数没有参数,在有GROUPING SETS子句的情况下,把它直接放在SELECT子句中,独占一列。它返回的结果是一个看起来像整形数值类型,其实是字符串的值,这个值使用了位图策略(bitvector,位向量),即它的二进制形式中的每1位标示着对应列是否参与GROUP BY,如果某一列参与了GROUP BY,对应位就被置为1,否则为0,根据这个位向量值和对应列是否显示为NULL,就可以解决上面提到的歧义问题了。

11.get_json_object(string json_string, string path)

语法:get_json_object(ctx,'$.category_name') p.s加$.符号


    返回值: string  


    说明:解析json的字符串json_string,返回path指定的内容。如果输入的json字符串无效,那么返回NULL。  

    类比:

    parse_url(‘http://facebook.com/path/p1.php?query=1‘, ‘HOST’)返回’facebook.com’ ,

    parse_url(‘http://facebook.com/path/p1.php?query=1‘, ‘PATH’)返回’/path/p1.php’ , 

    parse_url(‘http://facebook.com/path/p1.php?query=1‘, ‘QUERY’)返回’query=1’, 


12.日期增加函数 date_add(start_date, num_days)


返回类型:string


描述:返回增加num_days 天数的日期(负数则为减少)


date_add(start_date, num_days) - Returns the date that is num_days after start_date.


举例:


hive>select date_add('2014-09-16 15:50:08.119',10) from default.dual;


2014-09-26


hive>select date_add('2014-09-16 15:50:08.119',-10) from default.dual;


2014-09-06


13.日期减少函数 date_sub(start_date, num_days)


返回类型:string


描述:返回num_days 天数之前的日期(负数则为增加)


date_sub(start_date, num_days) - Returns the date that is num_days before start_date.


举例:


hive>select date_sub('2014-09-16 15:50:08.119',10) from default.dual;


2014-09-06


hive>select date_sub('2014-09-16 15:50:08.119',-10) from default.dual;


2014-09-26

三.查询优化

1.join前把不必要的数据滤掉,on字句不要加多余的判断(尽量尽早的过滤数据,减少每个阶段的数据量)

   (tb13.test_device_id=tb3.imei and tb3.device_id!='')

2.对于连续的数值,能用 between 就不要用 in 

    select id from t where num in(1,2,3)

   select id from t where num between 1 and 3


3.jion操作  

   小表要注意放在join的左边


   否则会引起磁盘和内存的大量消耗

4.not in

  select a.key from a left outer join b on a.key=b.key where b.key is null

5. 使用相同的连接键

   当对3个或者更多个表进行join连接时,如果每个on子句都使用相同的连接键的话,那么只会产生一个MapReduce job。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容