数据去重,用DISTINCT还是GROUP BY?

本文探讨了在SQL中数据去重时使用DISTINCT和GROUP BY的区别与优化策略。通过分析COUNT(*)、COUNT(col)、COUNT(DISTINCT col)的差异,解释了DISTINCT和GROUP BY在全表扫描、内存占用以及执行效率上的不同。在数据量较大时,由于DISTINCT操作可能导致数据倾斜和性能问题,建议使用GROUP BY进行数据去重。



1、背景概述


在执行某个去重计数任务时(部分SQL):

select count(distinct sta_id) num from tab_user

MapReduce Job卡在了最后一个ReduceTask,任务迟迟未运行成功,ReduceTask只有一个

如果某个Job任务卡在99%不动,例如,某个Reduce的时间比其他Reduce时间长的多,大部分Task在1分钟左右完成,只有一个Task执行半个小时还没完成。这时我们就应该考虑出现数据倾斜了

如果每个ReduceTask执行时间差不多,都特别长,不一定是数据倾斜导致的,可能是ReduceTask设置过少导致的。这时可以调整ReduceTask个数

一般一个Reduce处理的数据是1G(默认),所以首先想到的是能不能增加Reduce处理的数据量和个数来解决上述问题:

-- 指定每个Redcue处理的数据size
set hive.exec.reducers.bytes.per.reducer = 12000000;

-- 指定ReduceTask的个数
set mapred.reduce.tasks = 100;

经验证,调整了上述参数后,问题依旧没有得到解决

这种问题该怎么处理呢?问题的原因还得从以下两条SQL的区别与原理引出:

# SQL1
select count(distinct col) from t
# SQL2
select count(1) from (select distinct col from t)

本文的主题是介绍上述两条SQL的区别与原理,并对COUNT(DISTINCT)进行优化,进而解决上述问题

2、情景分析


首先准备测试数据:

-- 创建表
create table test (
    id string,
    name string,
    age bigint,
    gender bigint,
    score double
)

-- 插入数据
insert into test values
('1', 'a', 18, 1, 85),
('2', 'b', 19, 0, 80),
('3', 'c', 20, 1, 82),
('4', 'a', 21
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值