Hive 中 group by 和 distinct的区别

在 Hive 中,GROUP BYDISTINCT 都可用于去重或聚合,但实现机制不同、适用场景不同、性能也不同。在大多数情况下,GROUP BY 的效率更高,尤其是在需要配合聚合函数或处理大数据量时。


✅ 一、核心区别

特性GROUP BYDISTINCT
用途按字段分组,通常配合聚合函数(如 COUNT, SUM对 SELECT 列整体去重
语法SELECT col1, COUNT(*) FROM t GROUP BY col1;SELECT DISTINCT col1 FROM t;
执行阶段在 Reduce 阶段完成分组和聚合本质是 GROUP BY 所有 SELECT 字段的简写
优化支持支持倾斜优化(hive.groupby.skewindata)、向量化等优化空间小,底层仍转为 GROUP BY

🔍 关键事实:Hive 在底层会将 SELECT DISTINCT a, b 自动转换为 SELECT a, b FROM t GROUP BY a, b


✅ 二、性能对比(为什么 GROUP BY 更高效?)

场景 1:仅去重(无聚合)
-- 写法1
SELECT DISTINCT user_id FROM logs;

-- 写法2
SELECT user_id FROM logs GROUP BY user_id;

两者执行计划几乎相同,性能接近
GROUP BY 可额外开启优化:

SET hive.groupby.skewindata=true;  -- 处理数据倾斜

DISTINCT 无法直接使用这些参数。

场景 2:去重 + 聚合(常见数仓场景)
-- 需求:统计每个用户的订单数(天然用 GROUP BY)
SELECT user_id, COUNT(order_id) FROM orders GROUP BY user_id;

-- 若强行用 DISTINCT(无法实现!)
-- ❌ 无法同时返回 user_id 和 count

GROUP BY 是唯一选择,且可结合 Map 端预聚合优化:

SET hive.map.aggr=true;  -- Mapper 先局部聚合,减少 Shuffle 数据量
场景 3:多列去重
SELECT DISTINCT dept, city FROM employees;
-- 等价于
SELECT dept, city FROM employees GROUP BY dept, city;

✅ 两者一样,但 GROUP BY 更清晰,且便于后续扩展(如加 HAVING)。


✅ 三、特殊注意:COUNT(DISTINCT) 性能陷阱!

-- 反模式:大表上直接 COUNT(DISTINCT)
SELECT COUNT(DISTINCT user_id) FROM huge_table;

⚠️ 问题

  • 所有 user_id 都要发到 同一个 Reducer 去重(即使开启并行度也无效);
  • 极易导致 数据倾斜 + OOM + 超长运行时间

优化方案:改写为 GROUP BY + COUNT

-- 两阶段聚合(推荐)
SELECT COUNT(*) FROM (
  SELECT user_id FROM huge_table 
  GROUP BY user_id
) t;
  • 第一阶段:多个 Reducer 并行去重;
  • 第二阶段:汇总计数,避免单点瓶颈

💡 Hive 3.0+ 对 COUNT(DISTINCT) 有自动优化(近似或分阶段),但仍建议手动拆分。


📌 四、面试总结(一句话)

DISTINCT 本质是 GROUP BY 的语法糖,在 Hive 中性能相当或略差;而 GROUP BY 更灵活、可优化、支持聚合,是生产环境的首选。尤其对于 COUNT(DISTINCT),应主动改写为子查询 + GROUP BY 避免性能灾难。


✅ 最佳实践建议

  1. 优先使用 GROUP BY,语义清晰且可控;
  2. 避免直接 COUNT(DISTINCT big_column),改用两阶段聚合;
  3. 开启优化参数:
    SET hive.groupby.skewindata=true;   -- 防倾斜
    SET hive.map.aggr=true;             -- Map 端预聚合
    
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

走过冬季

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值