互联网技术 / 互联网资讯 · 2023年11月26日

Hive高级技巧:各种抽样方法

抽样

抽样在Hive 中也是比较常用的一种手段,主要用在下面的几个场景中

一些机器学习的场景中,数仓作为数据的提供方提供样本数据 数据的计算结果异常或者是指标异常,这个时候如果我们往往需要确认数据源的数据是否本身就有异常 SQL的性能有问题的时候我们也会使用抽样的方法区查看数据,然后进行SQL调优 在大规模数据量的数据分析及建模任务中,往往针对全量数据进行挖掘分析时会十分耗时和占用集群资源,因此一般情况下只需要抽取一小部分数据进行分析及建模操作。

随机抽样(Rand()函数)

我们一般情况下是使用排序函数和Rand() 函数来完成随机抽样,liMIT关键字限制抽样返回的数据,不同之处再有我们使用哪个排序函数呢

利用 Rand() 函数进行抽取,这是因为Rand() 返回一个0到1之间double 类型的随机值。

下面我们用到了前面我们使用过的一张表大概4603089 条记录,这里我就不给大家准备数据了,大家可以看Hive进阶之数据存储格式来获取测试数据

cReate table ods_User_bUCket_log( id int, naMe stRing, cITy stRing, phone stRing, acctiMe stRing) CLUSTERED BY (`id` ) INTO 5 BUCKETS Row foRFormat deliMITed fields teRMinated by ”” ”” sTored as textfile; inseRt OVeRwRITe table ods_User_bUCket_log select * fRoM ods_User_log;

oRdeR by Rand()

oRdeR by只会启用一个RedUCe所以比较耗时,至于为什么我们在前面的文章中解释过了Hive语法之常见排序方式

因为oRdeR by 是全局的,所以可以做到随机抽样的目的

select * fRoM ods_User_bUCket_log oRdeR by Rand() liMIT 10;

soRt by Rand()

soRt by 提供了单个 RedUCeR 内的排序功能,但不保证整体有序,这个时候其实不能做到真正的随机的,因为此时的随机是针对分区去的,所以如果我们可以通过控制进入每个分区的数据也是随机的话,那我们就可以做到随机了

select * fRoM ods_User_bUCket_log soRt by Rand() liMIT 10;

distRibute by Rand() soRt by Rand()

Rand函数前的distRibute和soRt关键字可以保证数据在MappeR和RedUCeR阶段是随机分布的,这个时候我们也能做到真正的随机,前面我们也介绍过clUSteR by 其实基本上是和distRibute by soRt by 等价的

select * fRoM ods_User_bUCket_log distRibute by Rand() soRt by Rand() liMIT 10;

clUSteR by Rand()

clUSteR by 的功能是 distRibute by 和 soRt by 的功能相结合,distRibute by Rand() soRt by Rand() 进行了两次随机,clUSteR by Rand() 仅一次随机,所以速度上会比上一种方法快

select * fRoM ods_User_bUCket_log clUSteR by Rand() liMIT 10;

tablesaMple()抽样函数

分桶抽样(桶表抽样)

Hive中分桶其实就是根据某一个字段Hash取模,放入指定数据的桶中,比如将表table按照ID分成100个桶,其算法是hash(id) % 100,这样,hash(id) % 100 = 0的数据被放到第一个桶中,hash(id) % 100 = 1的记录被放到第二个桶中。

分桶抽样语法:

TABLESAMPLE (BUCKET x out OF y [ON colnaMe])

其中x是要抽样的桶编号,桶编号从1开始,colnaMe表示抽样的列(也就是按照那个字段分桶),y表示桶的数量。所以表达的意思是按照colnaMe字段分成y桶,抽取其中的第x桶

SELECT * FROM ods_User_bUCket_log TABLESAMPLE (BUCKET 1 out OF 100000 ON Rand());

数据块抽样

从 Hive 0.8 开始提供块抽样,使用 tablesaMple 抽取指定的 行数/比例/大小

SELECT * FROM ods_User_data TABLESAMPLE(1000 ROWS); SELECT * FROM ods_User_data TABLESAMPLE (20 PERCENT); SELECT * FROM ods_User_data TABLESAMPLE(1M);

按比例抽样 ABLESAMPLE (20 PERCENT)

这将允许 Hive 至少获取 n%的数据

SELECT * FROM ods_User_bUCket_log TABLESAMPLE(0.0001 PERCENT);

抽取特定大小的数据TABLESAMPLE(100M)

SELECT * FROM ods_User_bUCket_log TABLESAMPLE(1M);

需要注意的是这里必须是整数M ,以为我尝试零点几的时候报错了

抽取特定的行数 TABLESAMPLE(10 ROWS)

OpenMagic API

Need more than content? Move into the product flow.

If you are here for model access, pricing, developer docs, or the future API console, the dedicated product path now lives on api.openmagic.ai.

登录免费注册