【问题标题】:Apache Hive different queries union, on the same table, with different where conditions in each query?Apache Hive 不同的查询联合,在同一张表上,每个查询中的条件不同?
【发布时间】:2014-09-16 11:32:34
【问题描述】:

我有一个名为“sales”的 Hive 表,结构如下:

id,ptype,amount,time,date
1,a,12,2240,2013-12-25
1,a,4,1830,2013-12-25
1,b,2,1920,2013-12-25
1,b,3,2023,2013-12-25
2,a,5,1220,2013-12-25
2,a,1,1320,2013-12-25

以下是我对不同变量变量的查询:

Q1: select id,sum(amount) as s_amt from sales group by id;
Q2: select id, sum(amount) as s_a_amt from sales where ptype='a' group by id;
Q3: select id, sum(amount) as s_b_amt from sales where ptype='b' group by id;

就我在 Hive 中学到的知识而言,只有当我们具有相同的列名或查询架构时,我们才能应用“union all”选项。以下是我想要使用 Hive 查询实现的最终结果:

id,s_amt,s_a_amt,s_b_amt
1,21,16,5
2,6,6,0

以下是我尝试过的一个查询,它成功执行。但是当您必须为超过 300 个变量设计相同的查询时,这将是一项非常痛苦的任务。考虑到我们有超过 300 个变量,是否有任何有效的方法来完成相同的任务?感谢您的 cmets!

    select t.id,max(t.s_amt) as s_amt,max(t.s_a_amt) as s_a_amt, max(t.s_b_amt) as s_b_amt
  from
     (select s1.id,sum(amount) as s_amt,0 as s_a_amt,0 as s_b_amt from sales s1 group by id union all
     select s2.id, 0 as s_amt, sum(amount) as s_a_amt, 0 as s_b_amt from sales s2 where ptype='a' group by id union all
     select s3.id, 0 as s_amt,0 as s_a_amt, sum(amount) as s_b_amt from sales s3 where ptype='b' group by id) t
group by t.id;

【问题讨论】:

    标签: hadoop hive union hdfs


    【解决方案1】:

    理想的解决方案是拥有一个

    IBM 所指的物化查询表 (MQT)。

    汇总表是 MQT 的特殊形式,而这正是您所需要的。快速定义——顾名思义,MQT 是一个简单的汇总表,在磁盘上实现。

    有了 MQT 支持,您只需完成以下操作

    CREATE MATERIALISED QUERY TABLE MQTA AS (
    select id, sum(amount) as s_a_amt from sales where ptype='a' group by id;
    )
    Data initially deferred 
    Refresh deferred
    Maintained by User
    

    最初延迟的数据表示不将汇总记录插入汇总表。 Refresh deferred 表示可以使用 REFRESH TABLE 语句随时刷新表中的数据。 由用户维护表示此表的引用必须由用户注意 - 由系统维护是另一个选项,其中系统会在以下情况下自动更新汇总表基表看到插入/删除//更新。

    您可以像简单的选择查询一样直接查询 MQT,汇总记录的所有繁重工作实际上都会在之前而不是在您查询 MQT 时运行,因此速度会快得多。

    但 AFAIK HIVE 不支持 MQT 或汇总表。

    您现在知道了这个概念,您只需要简单地模拟一下即可。创建一个汇总表并插入汇总记录(REFRESH TABLE 概念)。您必须通过使用某种上次加载日期字段进行控制来定期加载汇总值,以便在上次刷新后仅获取记录。您可以使用计划作业 - Hive 脚本来执行此操作。

    INSERT INTO PTYPE_AMOUNT_MQT AS (
    select *
      from
         (select s1.id,sum(amount) as s_amt,0 as s_a_amt,0 as s_b_amt from sales s1 where record_create_date > last_Refresh_date group by id union all
         select s2.id, 0 as s_amt, sum(amount) as s_a_amt, 0 as s_b_amt from sales s2 where ptype='a' and record_create_date > last_Refresh_date  group by id union all
         select s3.id, 0 as s_amt,0 as s_a_amt, sum(amount) as s_b_amt from sales s3 where ptype='b'  and record_create_date > last_Refresh_date group by id) 
    )
    

    拥有像 record_create_date 和 time 这样的审计字段总是好的。last_Refresh_date 是 上次你的工作运行

    【讨论】:

    • 非常感谢您的建议!这是一个很大的帮助:)
    • 嘿,随时告诉我这对你有什么影响
    • 当然...我会分享我的脚本 :)
    【解决方案2】:

    解决办法应该是:

    select id, sum(amount) s_amt, 
            SUM (CASE WHEN ptype='a' THEN amount 
                           ELSE 0
            END) sum_a_amt,
            SUM (CASE WHEN ptype='b' THEN amount 
                           ELSE 0
            END) sum_b_amt
    from sales 
    group by id;
    

    请尝试一下并告诉我它是否有效,我现在无法测试...

    【讨论】:

      【解决方案3】:

      Hive 最近添加了 GROUPING SETS 作为一项新功能 (https://issues.apache.org/jira/browse/HIVE-3471)。它可能比 MQT 更容易(写或读)。但并不是每个人都知道这个特性,正如 Arnaud 所说明的那样,CASE 函数的使用在实践中更为常用。

      【讨论】:

      • 是的..我看到了......我之前的查询(有 14 个变量)花了 30 分钟来处理 800 MB 文件..有 1 个 CPU 和 3.75 GB RAM......现在,使用案例功能,它下降到 8 分 38 秒..这是一个巨大的性能.. :)
      猜你喜欢
      • 1970-01-01
      • 2018-01-05
      • 1970-01-01
      • 2012-11-05
      • 2014-01-05
      • 2011-03-19
      • 1970-01-01
      • 1970-01-01
      • 2016-10-12
      相关资源
      最近更新 更多