HIVE优化场景一:去重场景问题

场景一 .去重场景问题

1)  UNION -- UNION ALL 之间的区别,如何取舍

2)  DISTINCT 替代方式 GROUP BY


1) UNION -- UNION ALL 之间的区别,如何取舍 

注意SQL 中 UNION ALL 与 UNION 是不一样的,

UNION ALL 不会对合并的数据去重

UNION 会对合并的数据去重

例子 :

EXPLAIN

SELECT

company_name

,dep_name

,user_id

,user_name

FROM datacube_salary_org

WHERE pt = '20200405'

UNION / UNION ALL

SELECT

  company_name

,dep_name

,user_id

,user_name

FROM datacube_salary_org

WHERE pt = '20200406'

;


UNION ALL  的 EXPLAIN 结果

STAGE DEPENDENCIES:

  Stage-1 is a root stage                         

  Stage-0 depends on stages: Stage-1             

STAGE PLANS:                                     

  Stage: Stage-1                                 

    Map Reduce                                   

      Map Operator Tree:                         

          TableScan                               

            alias: datacube_salary_org           

            filterExpr: (pt = '20200405') (type: boolean)

            Statistics: Num rows: 1 Data size: 342 Basic stats: COMPLETE Column stats: NONE

            Select Operator                       

              expressions: company_name (type: string), dep_name (type: string), user_id (type: bigint), user_name (type: string)

              outputColumnNames: _col0, _col1, _col2, _col3

              Statistics: Num rows: 1 Data size: 342 Basic stats: COMPLETE Column stats: NONE

              Union                               

                Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                File Output Operator             

                  compressed: false               

                  Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                  table:                         

                      input format: org.apache.hadoop.mapred.SequenceFileInputFormat

                      output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat

                      serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe

          TableScan                               

            alias: datacube_salary_org           

            filterExpr: (pt = '20200406') (type: boolean)

            Statistics: Num rows: 1 Data size: 412 Basic stats: COMPLETE Column stats: NONE

            Select Operator                       

              expressions: company_name (type: string), dep_name (type: string), user_id (type: bigint), user_name (type: string)

              outputColumnNames: _col0, _col1, _col2, _col3

              Statistics: Num rows: 1 Data size: 412 Basic stats: COMPLETE Column stats: NONE

              Union                               

                Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                File Output Operator             

                  compressed: false               

                  Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                  table:                         

                      input format: org.apache.hadoop.mapred.SequenceFileInputFormat

                      output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat

                      serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe


  Stage: Stage-0                                 

    Fetch Operator                               

      limit: -1                                   

      Processor Tree:                             

        ListSink         


UNION  的 EXPLAIN 结果

STAGE DEPENDENCIES:                               

  Stage-1 is a root stage                         

  Stage-0 depends on stages: Stage-1             

STAGE PLANS:                                     

  Stage: Stage-1                                 

    Map Reduce                                   

      Map Operator Tree:                         

          TableScan                               

            alias: datacube_salary_org           

            filterExpr: (pt = '20200405') (type: boolean)

            Statistics: Num rows: 1 Data size: 342 Basic stats: COMPLETE Column stats: NONE

            Select Operator                       

              expressions: company_name (type: string), dep_name (type: string), user_id (type: bigint), user_name (type: string)

              outputColumnNames: _col0, _col1, _col2, _col3

              Statistics: Num rows: 1 Data size: 342 Basic stats: COMPLETE Column stats: NONE

              Union                               

                Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                Group By Operator                 

                  keys: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                  mode: hash                     

                  outputColumnNames: _col0, _col1, _col2, _col3

                  Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                  Reduce Output Operator         

                    key expressions: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                    sort order: ++++             

                    Map-reduce partition columns: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                    Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

          TableScan                               

            alias: datacube_salary_org           

            filterExpr: (pt = '20200406') (type: boolean)

            Statistics: Num rows: 1 Data size: 412 Basic stats: COMPLETE Column stats: NONE

            Select Operator                       

              expressions: company_name (type: string), dep_name (type: string), user_id (type: bigint), user_name (type: string)

              outputColumnNames: _col0, _col1, _col2, _col3

              Statistics: Num rows: 1 Data size: 412 Basic stats: COMPLETE Column stats: NONE

              Union                               

                Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                Group By Operator                 

                  keys: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                  mode: hash                     

                  outputColumnNames: _col0, _col1, _col2, _col3

                  Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                  Reduce Output Operator         

                    key expressions: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                    sort order: ++++             

                    Map-reduce partition columns: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                    Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

      Reduce Operator Tree:                       

        Group By Operator                         

          keys: KEY._col0 (type: string), KEY._col1 (type: string), KEY._col2 (type: bigint), KEY._col3 (type: string)

          mode: mergepartial                     

          outputColumnNames: _col0, _col1, _col2, _col3

          Statistics: Num rows: 1 Data size: 377 Basic stats: COMPLETE Column stats: NONE

          File Output Operator                   

            compressed: false                     

            Statistics: Num rows: 1 Data size: 377 Basic stats: COMPLETE Column stats: NONE

            table:                               

                input format: org.apache.hadoop.mapred.SequenceFileInputFormat

                output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat

                serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe


  Stage: Stage-0                                 

    Fetch Operator                               

      limit: -1                                   

      Processor Tree:                             

        ListSink                                 

     对比两个的EXPLAIN 结果,我们不难发现,UNION 会多出一个Reduce 流程。这也不难理,为什么在无去重需求下,使用 UNION ALL 而不是 UNION 。


另外据说 使用 UNION ALL ,再去使用  GROUP BY 去做去重效果 会比 UNION 效率要更高。

SELECT 

 company_name

 ,dep_name

 ,user_id

 ,user_name

FROM datacube_salary_org

WHERE pt = '20200405'

UNION 

SELECT

  company_name

 ,dep_name

 ,user_id

 ,user_name

FROM datacube_salary_org

WHERE pt = '20200406'

;

改为

SELECT

company_name

,dep_name

,user_id

,user_name

FROM

(

SELECT

company_name

,dep_name

,user_id

,user_name

FROM datacube_salary_org

WHERE pt = '20200405'

UNION ALL

SELECT

  company_name

,dep_name

,user_id

,user_name

FROM datacube_salary_org

WHERE pt = '20200406'

) tmp

GROUP BY

company_name

,dep_name

,user_id

,user_name

;

我认为效率一致,看下改进方式的 EXPLAIN 结果

STAGE DEPENDENCIES:

  Stage-1 is a root stage                         

  Stage-0 depends on stages: Stage-1             


STAGE PLANS:                                     

  Stage: Stage-1                                 

    Map Reduce                                   

      Map Operator Tree:                         

          TableScan                               

            alias: datacube_salary_org           

            filterExpr: (pt = '20200405') (type: boolean)

            Statistics: Num rows: 1 Data size: 342 Basic stats: COMPLETE Column stats: NONE

            Select Operator                       

              expressions: company_name (type: string), dep_name (type: string), user_id (type: bigint), user_name (type: string)

              outputColumnNames: _col0, _col1, _col2, _col3

              Statistics: Num rows: 1 Data size: 342 Basic stats: COMPLETE Column stats: NONE

              Union                               

                Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                Group By Operator                 

                  keys: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                  mode: hash                     

                  outputColumnNames: _col0, _col1, _col2, _col3

                  Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                  Reduce Output Operator         

                    key expressions: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                    sort order: ++++             

                    Map-reduce partition columns: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                    Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

          TableScan                               

            alias: datacube_salary_org           

            filterExpr: (pt = '20200406') (type: boolean)

            Statistics: Num rows: 1 Data size: 412 Basic stats: COMPLETE Column stats: NONE

            Select Operator                       

              expressions: company_name (type: string), dep_name (type: string), user_id (type: bigint), user_name (type: string)

              outputColumnNames: _col0, _col1, _col2, _col3

              Statistics: Num rows: 1 Data size: 412 Basic stats: COMPLETE Column stats: NONE

              Union                               

                Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                Group By Operator                 

                  keys: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                  mode: hash                     

                  outputColumnNames: _col0, _col1, _col2, _col3

                  Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

                  Reduce Output Operator         

                    key expressions: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                    sort order: ++++             

                    Map-reduce partition columns: _col0 (type: string), _col1 (type: string), _col2 (type: bigint), _col3 (type: string)

                    Statistics: Num rows: 2 Data size: 754 Basic stats: COMPLETE Column stats: NONE

      Reduce Operator Tree:                       

        Group By Operator                         

          keys: KEY._col0 (type: string), KEY._col1 (type: string), KEY._col2 (type: bigint), KEY._col3 (type: string)

          mode: mergepartial                     

          outputColumnNames: _col0, _col1, _col2, _col3

          Statistics: Num rows: 1 Data size: 377 Basic stats: COMPLETE Column stats: NONE

          File Output Operator                   

            compressed: false                     

            Statistics: Num rows: 1 Data size: 377 Basic stats: COMPLETE Column stats: NONE

            table:                               

                input format: org.apache.hadoop.mapred.SequenceFileInputFormat

                output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat

                serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe


  Stage: Stage-0                                 

    Fetch Operator                               

      limit: -1                                   

      Processor Tree:                             

        ListSink 

两个方式的EXPLAIN 无区别,故认为没优化

对比下时间(小数据量级)UNION ALL 和 GROUP BY    耗时都是 5.2s

经过以上对比,可以认为无差别



2)  DISTINCT 替代方式 GROUP BY

在实际的去重场景中,我们会选用 DISTINCT 去做去重。

但是实际场景下,选择 GROUP BY 效率会更高。下面我们进行下实验。

我们先选用低效率的 COUNT(DISTINCT ) 方式 

SQL

SELECT

COUNT(DISTINCT company_name, dep_name, user_id)

FROM datacube_salary_org

;

STAGE DEPENDENCIES:

  Stage-1 is a root stage                         

  Stage-0 depends on stages: Stage-1             


STAGE PLANS:                                     

  Stage: Stage-1                                 

    Map Reduce                                   

      Map Operator Tree:                         

          TableScan                               

            alias: datacube_salary_org           

            Statistics: Num rows: 7 Data size: 340 Basic stats: COMPLETE Column stats: NONE

            Select Operator                       

              expressions: company_name (type: string), dep_name (type: string), user_id (type: bigint)

              outputColumnNames: company_name, dep_name, user_id

              Statistics: Num rows: 7 Data size: 340 Basic stats: COMPLETE Column stats: NONE

              Group By Operator                   

                aggregations: count(DISTINCT company_name, dep_name, user_id)

                keys: company_name (type: string), dep_name (type: string), user_id (type: bigint)

                mode: hash                       

                outputColumnNames: _col0, _col1, _col2, _col3

                Statistics: Num rows: 7 Data size: 340 Basic stats: COMPLETE Column stats: NONE

                Reduce Output Operator           

                  key expressions: _col0 (type: string), _col1 (type: string), _col2 (type: bigint)

                  sort order: +++                 

                  Statistics: Num rows: 7 Data size: 340 Basic stats: COMPLETE Column stats: NONE

      Reduce Operator Tree:                       

        Group By Operator                         

          aggregations: count(DISTINCT KEY._col0:0._col0, KEY._col0:0._col1, KEY._col0:0._col2)

          mode: mergepartial                     

          outputColumnNames: _col0               

          Statistics: Num rows: 1 Data size: 16 Basic stats: COMPLETE Column stats: NONE

          File Output Operator                   

            compressed: false                     

            Statistics: Num rows: 1 Data size: 16 Basic stats: COMPLETE Column stats: NONE

            table:                               

                input format: org.apache.hadoop.mapred.SequenceFileInputFormat

                output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat

                serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe


  Stage: Stage-0                                 

    Fetch Operator                               

      limit: -1                                   

      Processor Tree:                             

        ListSink

小数据量运行时间为4s

====================

我们再选用高效率的 GROUP BY 方式

SQL

SELECT COUNT(1)

FROM (

SELECT

company_name

,dep_name

,user_id

FROM datacube_salary_org

GROUP BY

company_name

,dep_name

,user_id

) AS tmp

;

EXPLAIN 结果

STAGE DEPENDENCIES:

  Stage-1 is a root stage                         

  Stage-2 depends on stages: Stage-1             

  Stage-0 depends on stages: Stage-2             


STAGE PLANS:                                     

  Stage: Stage-1                                 

    Map Reduce                                   

      Map Operator Tree:                         

          TableScan                               

            alias: datacube_salary_org           

            Statistics: Num rows: 7 Data size: 340 Basic stats: COMPLETE Column stats: NONE

            Select Operator                       

              expressions: company_name (type: string), dep_name (type: string), user_id (type: bigint)

              outputColumnNames: company_name, dep_name, user_id

              Statistics: Num rows: 7 Data size: 340 Basic stats: COMPLETE Column stats: NONE

              Group By Operator                   

                keys: company_name (type: string), dep_name (type: string), user_id (type: bigint)

                mode: hash                       

                outputColumnNames: _col0, _col1, _col2

                Statistics: Num rows: 7 Data size: 340 Basic stats: COMPLETE Column stats: NONE

                Reduce Output Operator           

                  key expressions: _col0 (type: string), _col1 (type: string), _col2 (type: bigint)

                  sort order: +++                 

                  Map-reduce partition columns: _col0 (type: string), _col1 (type: string), _col2 (type: bigint)

                  Statistics: Num rows: 7 Data size: 340 Basic stats: COMPLETE Column stats: NONE

      Reduce Operator Tree:                       

        Group By Operator                         

          keys: KEY._col0 (type: string), KEY._col1 (type: string), KEY._col2 (type: bigint)

          mode: mergepartial                     

          outputColumnNames: _col0, _col1, _col2 

          Statistics: Num rows: 3 Data size: 145 Basic stats: COMPLETE Column stats: NONE

          Select Operator                         

            Statistics: Num rows: 3 Data size: 145 Basic stats: COMPLETE Column stats: NONE

            Group By Operator                     

              aggregations: count(1)             

              mode: hash                         

              outputColumnNames: _col0           

              Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE

              File Output Operator               

                compressed: false                 

                table:                           

                    input format: org.apache.hadoop.mapred.SequenceFileInputFormat

                    output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat

                    serde: org.apache.hadoop.hive.serde2.lazybinary.LazyBinarySerDe


  Stage: Stage-2                                 

    Map Reduce                                   

      Map Operator Tree:                         

          TableScan                               

            Reduce Output Operator               

              sort order:                         

              Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE

              value expressions: _col0 (type: bigint)

      Reduce Operator Tree:                       

        Group By Operator                         

          aggregations: count(VALUE._col0)       

          mode: mergepartial                     

          outputColumnNames: _col0               

          Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE

          File Output Operator                   

            compressed: false                     

            Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: NONE

            table:                               

                input format: org.apache.hadoop.mapred.SequenceFileInputFormat

                output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat

                serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe


  Stage: Stage-0                                 

    Fetch Operator                               

      limit: -1                                   

      Processor Tree:                             

        ListSink 

小数据量运行时间8s

优化原理:

我们先说下为什么大数据集下  先 GROUP BY 再COUNT 的效率 要优于 直接 COUNT(DISTINCT ...) .

因为 COUNT(DISTINCT ...)  , 会把相关的列组成一个key 传入到 Reducer 中。即 count(DISTINCT KEY._col0:0._col0, KEY._col0:0._col1, KEY._col0:0._col2) |   这样需要在 一个 Reducer 中 ,完成全排序并去重。

先GROUP BY 再去 COUNT ,则GROUP BY 可以 将不同的KEY , 分发到多个 Reducer 中,在 GROUP BY流程中完成了去重。此时,去重时并不会把数据放入到 一个 Reducer 中,利用了分布式的优势。这个去重效率更高。在下一步 COUNT 阶段,再将上一步奏 GROUP BY 去重后的 KEY , 进行统计计算。

所以大数据量下 先GROUP BY ,再去 COUNT    效率比  COUNT(DISTINCT)  更高。

我们对比下上述的小数据量运行结果

EXPLAIN 中 :COUNT(DISTINCT )  比  先GROUP BY 再 COUNT  的阶段少 。因为 GROUP BY 已经是一个 MR STAGE,  而 COUNT 是另一个 STAGE.

运行时间上 :可以看到两者并无差别,甚至  COUNT(DISTINCT ) 总时间小于    先GROUP BY 再 COUNT。这是因为,运行一个 STAGE 需要申请资源,开辟资源,有时间成本。故小数据量下 , 先GROUP BY 再 COUNT 时间多于 COUNT(DISTINCT ) , 主要是花费在 申请资源,创建容器的时间上。

并且 总运行时间  COUNT(DISTINCT ) 小于  先GROUP BY 再 COUNT

产生上述结果的原因,还是因为数据集大小的问题。即 一个 Reducer 全局排序的时间成本,与划分多个作业阶段申请资源的成本的比较 !!!

因此,我们因根据实际的数据量做合理的取舍 !!!!

————————————————

本文声明:本文为CSDN博主「高达一号」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/u010003835/article/details/105493563

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

推荐阅读更多精彩内容