【数据库】HIVE SQL中三种join中的坑(自动过滤掉两边同为null的数据)

本文探讨了在SQL中处理NULL值的策略,特别是在where条件、union all、full join及join操作中,通过使用coalesce函数确保NULL值正确参与比较,避免了空值引起的筛选遗漏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    最近在使用union all的过程中,遇到了一些问题,又GET了一个知识点,作为一个总结,记录一下~

where条件的坑:

案例,若一个字段的值为1,2,NULL(自然空,而不是'NULL')这时,如果代码这样写:

select id,data,name 
  from aa
 where name <> 'us'

那么,为空的这一条记录是不会被筛选出来的。

iddatename
39148105112017-06-15hk
39148519662017-06-15hk

name为空的这一条就不会显示。

如果,这种情况就要通过转化才能达到想要的效果:

select *id,data,name 
  from a
 where coalesce(name,0) <> 'us'

结果:

iddatename
39121156252017-06-15NULL
39148105112017-06-15hk
39148519662017-06-15

hk

 

 

 

下面来讲一下full join,也会出现这样的问题,现在同一张表full join:

select a.id   as aid,
       a.date as adate,
       coalesce(a.name,b.name) as name,
       b.id   as bid,
       b.date as bdate
  from aa a
  full join aa b
    on a.name = b.name

结果为:

aidadatenamebidbdate
39121156252017-06-15NULLNULLNULL
NULLNULLNULL39121156252017-06-15
39148519662017-06-15hk39148519662017-06-15
39148519662017-06-15hk39148105112017-06-15
39148105112017-06-15hk39148519662017-06-15
39148105112017-06-15hk39148105112017-06-15
39204086382017-06-15us3920408638

2017-06-15

 

 

 

因此,也要做相应的处理才可以:

select a.id   as aid,
       a.date as adate,
       coalesce(a.name,b.name) as name,
       b.id   as bid,
       b.date as bdate
  from aa a
  full join aa b
    on coalesce(a.name,0) = coalesce(b.name,0)

结果为:

aidadatenamebidbdate
39121156252017-06-15NULL39121156252017-06-15
39148519662017-06-15hk39148519662017-06-15
39148519662017-06-15hk39148105112017-06-15
39148105112017-06-15hk39148519662017-06-15
39148105112017-06-15hk39148105112017-06-15
39204086382017-06-15us39204086382017-06-15

left join不会有这种问题,我也测试了一下:

select a.id   as aid,
       a.date as adate,
       coalesce(a.name,b.name) as name,
       b.id   as bid,
       b.date as bdate
  from aa a
  left join aa b
    on a.name = b.name

结果为:

aidadatenamebidbdate
39121156252017-06-15NULLNULLNULL
39148105112017-06-15hk39148519662017-06-15
39148105112017-06-15hk39148105112017-06-15
39148519662017-06-15hk39148519662017-06-15
39148519662017-06-15hk39148105112017-06-15
39204086382017-06-15us3920408638

2017-06-15

 

 

 

那么join呢,我也测试了一下:

select a.id   as aid,
       a.date as adate,
       coalesce(a.name,b.name) as name,
       b.id   as bid,
       b.date as bdate
  from aa a
  join aa b
    on a.name = b.name

结果为:

aidadatenamebidbdate
39148105112017-06-15hk39148519662017-06-15
39148105112017-06-15hk39148105112017-06-15
39148519662017-06-15hk39148519662017-06-15
39148519662017-06-15hk39148105112017-06-15
39204086382017-06-15us39204086382017-06-15

 

也有这样的问题,为null的结果不展示。

select a.id   as aid,
       a.date as adate,
       coalesce(a.name,b.name) as name,
       b.id   as bid,
       b.date as bdate
  from aa a
  join aa b
    on coalesce(a.name,0) = coalesce(b.name,0)
aidadatenamebidbdate
39121156252017-06-15NULL39121156252017-06-15
39148105112017-06-15hk39148519662017-06-15
39148105112017-06-15hk39148105112017-06-15
39148519662017-06-15hk39148519662017-06-15
39148519662017-06-15hk39148105112017-06-15
39204086382017-06-15us3920408638

2017-06-15

 

 

 

这次探讨的问题就到这里啦,如果还有别的部分,我后续会在更新~

<think>嗯,用户现在问的是HiveSQL中有几种mapjoin方式。之前他们问过Hive大表join的优化,所以可能现在想更深入了解mapjoin的具体实现方式。首先,我需要回忆Hive中mapjoin的不同类型,以及它们的适用场景和配置方式。 用户之前的问题是关于大表join优化的,所以这次的问题应该是在优化策略中的mapjoin部分更深入。我需要确保回答覆盖不同的mapjoin方式,比如自动mapjoin、手动提示、参数控制、基于分桶的mapjoin,以及分布式缓存的使用。 记得用户可能关心如何配置这些方式,以及各自的优缺点。比如自动mapjoin是根据表的大小自动判断,而手动提示则是通过注释来指定。还有基于分桶的mapjoin需要表结构支持分桶,这可能适用于特定场景。 另外,用户可能想知道每种方式的使用场景,例如当小表超过默认阈值时,如何调整参数,或者如何强制使用mapjoin。需要给出具体的例子和配置参数,这样用户可以直接应用。 还需要注意用户可能的误区,比如所有小表都适合mapjoin,但实际上如果小表过大,可能会导致内存问题。因此,在解释时需要提到阈值调整和内存管理的重要性。 最后,确保回答结构清晰,分点说明,并且结合之前的优化策略,让用户能够连贯地理解不同mapjoin方式在整体优化中的位置和作用。</think>在 Hive SQL 中,**MapJoin**(Map 端 Join)是优化 Join 操作的重要手段,尤其适合 **小表与大表关联** 的场景。其核心思想是 **将小表直接加载到内存**,在 Map 阶段完成 Join 操作,避免 Reduce 阶段的数据倾斜和 Shuffle 开销。以下是 Hive 中常见的 MapJoin 实现方式及使用场景: --- ### 一、自动 MapJoin(Auto MapJoin) **原理**:Hive 自动判断小表是否满足阈值,若满足则自动转换为 MapJoin。 **配置参数**: ```sql -- 开启自动 MapJoin(默认开启) SET hive.auto.convert.join = true; -- 设置小表阈值(默认约 25MB) SET hive.auto.convert.join.noconditionaltask.size = 25165824; -- 24MB ``` **触发条件**: 1. 小表总大小 ≤ `hive.auto.convert.join.noconditionaltask.size`; 2. 参与 Join 的表为非分桶表(分桶表需特殊处理)。 **示例**: ```sql SELECT /*+ MAPJOIN(small_table) */ big_table.id, small_table.name FROM big_table JOIN small_table ON big_table.id = small_table.id; ``` --- ### 二、手动强制 MapJoin(Hint 提示) **原理**:通过 SQL 注释 `/*+ MAPJOIN(table_name) */` 强制指定小表为 MapJoin。 **适用场景**: - 自动 MapJoin 未触发时(如小表略超阈值但内存充足); - 需要明确控制 Join 逻辑。 **示例**: ```sql SELECT /*+ MAPJOIN(small_table) */ big_table.id, small_table.name FROM big_table JOIN small_table ON big_table.id = small_table.id; ``` --- ### 三、分桶 MapJoin(Bucket MapJoin) **原理**:若两表均按 Join Key 分桶且分桶数成倍数关系,Hive 可对分桶数据进行本地 Join,无需全局 Shuffle。 **配置参数**: ```sql SET hive.optimize.bucketmapjoin = true; ``` **触发条件**: 1. 两表均为分桶表,且分桶字段 = Join Key; 2. 大表的分桶数是小表分桶数的整数倍。 **示例**: ```sql -- 创建分桶表 CREATE TABLE big_table_bucketed (id INT) CLUSTERED BY (id) INTO 32 BUCKETS; CREATE TABLE small_table_bucketed (id INT) CLUSTERED BY (id) INTO 16 BUCKETS; -- 执行分桶 MapJoin SELECT /*+ MAPJOIN(small_table_bucketed) */ big_table_bucketed.id, small_table_bucketed.name FROM big_table_bucketed JOIN small_table_bucketed ON big_table_bucketed.id = small_table_bucketed.id; ``` --- ### 四、分布式缓存(Distributed Cache)优化 **原理**:将小表文件广播到所有 Map Task 节点,避免重复拉取数据。 **适用场景**: - 小表为静态表(如维度表),且频繁与大表 Join; - 小表无法直接通过 Hive 参数触发 MapJoin(如复杂子查询结果)。 **配置方式**: ```sql -- 将小表添加到分布式缓存 ADD FILE /path/to/small_table.csv; ``` --- ### 五、参数调优与注意事项 1. **内存管理**: ```sql SET hive.mapjoin.smalltable.filesize = 25000000; -- 调整小表阈值 SET hive.mapjoin.localtask.max.memory.usage = 0.9; -- 限制内存使用比例 ``` 2. **数据倾斜处理**:若小表中某些 Key 数据量过大,可能导致内存溢出,需提前过滤或拆分。 3. **ORC/Parquet 列式存储**:使用列存格式可减少 I/O 和内存占用,提升 MapJoin 效率。 --- ### 总结对比 | **方式** | **适用场景** | **优点** | **缺点** | |--------------------|--------------------------------|--------------------------|-----------------------------| | 自动 MapJoin | 小表符合默认阈值 | 无需手动干预,Hive 自动优化 | 阈值固定,需调整参数 | | 手动 Hint MapJoin | 小表略超阈值或需强制控制逻辑 | 灵活可控 | 需人工判断是否适用 | | 分桶 MapJoin | 两表均为分桶表且分桶数匹配 | 避免 Shuffle,高效本地 Join | 需预先分桶,维护成本高 | | 分布式缓存 | 静态小表或复杂子查询结果 | 减少网络传输 | 需手动管理文件 | 根据实际数据量、表结构和资源情况选择合适的 MapJoin 策略,可显著提升 Hive Join 性能。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值