Hive不支持非相等的join

由于 hive 与传统关系型数据库面对的业务场景及底层技术架构都有着很大差异,因此,传统数据库领域的一些技能放到 Hive 中可能已不再适用。关于 hive 的优化与原理、应用的文章,前面也陆陆续续的介绍了一些,但大多都偏向理论层面,本文就介绍一个实例,从实例中一步步加深对 hive 调优的认识与意识。

1、需求

需求我做了简化,很简单,两张表做个 join,求指定城市,每天的 pv,用传统的 RDBMS SQL 写出来就这样的:

SELECT t.statdate,
  c.cname,
  count(t.cookieid)
FROM tmpdb.city c
JOIN ecdata.ext_trackflow t ON (t.area1= c.cname
            OR t.area2 =c.cname
            OR t.area3 = c.cname)
WHERE t.statdate>=‘20140818‘ and t.statdate<=‘20140824‘
  AND platform=‘pc‘
GROUP BY t.statdate,
    c.cname;

怎么样?根据 SQL 看懂需求没问题吧?

2、非等值 join 问题

然后把这条 SQL 贴到 hive 中去执行,然后你会发现报错了:

FAILED: SemanticException [Error 10019]: Line 5:32 OR not supported in JOIN currently ‘cname‘

这是因为 hive 受限于 MapReduce 算法模型,只支持 equi-joins(等值 join),要实现上述的非等值 join,你可以采用笛卡儿积( full Cartesian product )来实现:

SELECT t.statdate,
  c.cname,
  count(t.cookieid)
FROM tmpdb.city c
JOIN ecdata.ext_trackflow t
WHERE t.statdate>=‘20140818‘
  AND t.statdate<=‘20140824‘
  AND platform=‘pc‘
  AND (t.area1= c.cname
  OR t.area2 =c.cname
  OR t.area3 = c.cname)
GROUP BY t.statdate,
    c.cname;

然后再拿着这条语句执行下。

改写非等值 join:union all

既然不允许非等值 join,那我们换一下思路,多个子查询 union all,然后汇总:

SELECT dt,
       name,
       count(cid)
FROM
  (SELECT t.statdate dt,
          c.cname name,
          t.cookieid cid
   FROM tmpdb.city c
   JOIN ecdata.ext_trackflow t ON t.area1 =c.cname
   WHERE t.statdate>=‘20140818‘
     AND t.statdate<=‘20140824‘
     AND platform=‘pc‘
   UNION ALL SELECT t.statdate dt,
     c.cname name,
     t.cookieid cid
   FROM tmpdb.city c
   JOIN ecdata.ext_trackflow t ON t.area2 =c.cname
   WHERE t.statdate>=‘20140818‘
     AND t.statdate<=‘20140824‘
     AND platform=‘pc‘
   UNION ALL SELECT t.statdate dt,
     c.cname name,
     t.cookieid cid
   FROM tmpdb.city c
   JOIN ecdata.ext_trackflow t ON t.area3 =c.cname
   WHERE t.statdate>=‘20140818‘
     AND t.statdate<=‘20140824‘
     AND platform=‘pc‘) tmp_trackflow
GROUP BY dt,
         name;
时间: 2024-10-03 07:50:32

Hive不支持非相等的join的相关文章

Pentaho的Mondrian对Hive的支持

需求描述 考虑直接在Hive或者Impala等Big Data方案,能够支持MDX查询,现调研一下Mondrian对hive的支持情况. 环境准备 hive环境,采用hive-0.10-cdh4.2.1 客户端程序使用的类库:mondrian-3.6.0.olap4j-1.2.0-SNAPSHOT 数据准备 来源于网上一个数据源,准备四张表 Customer - 客户信息维表 Product - 产品维表 ProductType - 产品类表维表 Sale - 销售记录表 为了方便测试数据与MD

如何为SparkSQL添加hive中支持的而SparkSQL暂未支持的命令

以ANALYZE为例描述 ANALYZE在Hive中的使用方法详见:https://cwiki.apache.org/confluence/display/Hive/StatsDev#StatsDev-ExistingTables ANALYZE在Hive中使用简单介绍 一张表有4个分区: Partition1: (ds='2008-04-08', hr=11) Partition2: (ds='2008-04-08', hr=12) Partition3: (ds='2008-04-09',

Newtonsoft.Json高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称

手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数据,经过分析一个简单的列表接口每一行数据返回了16个字段,但是手机APP端只用到了其中7个字段,剩余9个字段的数据全部都是多余的,如果接口返回数据为40K大小,也就是说大约20K的数据为无效数据,3G网络下20K下载差不多需要1s,不返回无效数据至少可以节约1s的时间,大大提高用户体验.本篇将为大家

hive不支持多个字符作为分隔符的解决方案

题记: 近期在做某个大型银行的大数据项目,当在处理非结构化数据时,却发现他们给的数据并不符合hive和pig的处理要求,数据每行必须需要多个分割符才能完美处理,一下午也没有想到完美的办法解决,今天重新审视了一下整个过程.看来hive的命令行没法搞定了.于是乎,只能通过代码来搞定. 1.重新实现hive的InputFormat了,别急放码过来 package hiveStream; import java.io.IOException; import org.apache.hadoop.io.Lo

hive中与hbase外部表join时内存溢出(hive处理mapjoin的优化器机制)

与hbase外部表(wizad_mdm_main)进行join出现问题: CREATE TABLE wizad_mdm_dev_lmj_edition_result as select * from  wizad_mdm_dev_lmj_20141120 as w JOIN wizad_mdm_main as a ON (a.rowkey = w.guid); 程序启动后,死循环,无反应.最后在进行到0.83时,内存溢出失败. 原因: 默认情况下,Hive会自动将小表加到DistributeCa

[Hive]Hive数据倾斜(大表join大表)

业务背景 用户轨迹工程的性能瓶颈一直是etract_track_info,其中耗时大户主要在于trackinfo与pm_info进行左关联的环节,trackinfo与pm_info两张表均为GB级别,左关联代码块如下: from trackinfo a left outer join pm_info b on (a.ext_field7 = b.id) 使用以上代码块需要耗时1.5小时. 优化流程 第一次优化 考虑到pm_info表的id是bigint类型,trackinfo表的ext_fiel

Spark SQL读取MySQL的dept和hive的emp表,做join和分组查询,后写到json

val jdbcDF = spark.read.format("jdbc").option("url", "jdbc:mysql://hadoop000:3306").option("dbtable", "hive.dept").option("user", "root").option("password", "123456"

MS Acess不支持多个left join(语法错误(操作符丢失)在查询表达式 xx中)

如图: sql语句如下 select p.*,c.[name] as compName,s.[name] as sellerName from percentage p left join company c on c.id = p.compId left join seller s on s.id = p.sellerId 解决方法: 在第一个left join附近加() select p.*,c.[name] as compName,s.[name] as sellerName from (

Hive 中Join的专题---Join详解

1.什么是等值连接? 2.hive转换多表join时,如果每个表在join字句中,使用的都是同一个列,该如何处理? 3.LEFT,RIGHT,FULL OUTER连接的作用是什么? 4.LEFT或RIGHT join是连接从左边还有右边? Hive表连接的语法支持如下: Sql代码  : join_table: table_reference JOIN table_factor [join_condition] | table_reference {LEFT|RIGHT|FULL} [OUTER