使用Maxcomputer SQL对数据进行抽样

本文涉及的产品
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
简介: 在大数据量分析任务中,针对全量数据进行分析挖掘会存在困难,抽样就显得格外重要了

一、概述

在Hive中有三种方式可以进行对数据抽样:随机抽样、数据块抽样、分桶抽样、分层抽样。现在我们逐一看下在MaxComputer中如何使用

二、构造数据

表tb有如下数据

with tb as(select    id,    det
fromvalues(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h'),(9,'i'),(10,'j'),(11,'k'),(12,'l'),(13,'m'),(14,'n'),(15,'o'),(16,'p'),(17,'q'),(18,'r'),(19,'s'),(20,'t'),(21,'u'),(22,'v'),(23,'w'),(24,'x'),(25,'y'),(26,'z')             t(id,det))

三、数据抽样

1.随机抽样(ODPS)

MaxComputer中有个随机函数rand(),可以通过rand()函数对数据进行抽样;

MaxComputer中cluster_sample()函数随机抽取N条数据或按比例抽取

1.order by rand()

select*from tb orderby rand()limit5;id  det
1 a
4 d
22  v
13  m
11  k

运行几次之后发现结果都一样,好像没有达到随机取数的效果,从sql来理解,上面的语句相当于生成了一个随机序列,每条记录都分配了一个随机值,然后所有记录按照随机值排序,从排序结果中取前5条,以此达到随机选择的目的。

   然后rand()方法产生随机数需要使用随机数种子,相同随机数种子产生的随机数永远都是一样的。当不传递随机数种子时,函数将使用默认的固定随机数种子,所以无论运行多少次,产生的随机数都是固定的(可以通过seed确定随机数序列,seed确定后,即可固定该函数的返回结果。执行环境是一样的情况下,seed取值不变的话,返回值是一样的,如果需要返回不一样的结果,需要修改seed取值)

解决这个问题,我们传入随时变化的seed即可

select*from tb orderby rand(unix_timestamp())limit5;id  det
22  v
3 c
1 a
19  s
13  m

2.distribute by rand() sort by rand()

其中rand函数前的distribute和sort关键字可以保证数据在mapper和reducer阶段是随机分布的。

select*from tb distribute by rand() sort by rand()limit5;id  det
9 i
7 g
24  x
17  q
16  p

同样如果想要每次运行随机结果都不一样,rand()函数里加上随机值seed

3.cluster by rand()

select*from tb cluster by rand()limit5;id  det
9 i
1 a
15  o
13  m
6 f

如果想要每次运行随机结果都不一样,rand()函数里加上随机值seed。

这里插一个知识点:order by、sort by、 distribute by和 cluster by区别:

order by主要是做全局排序。只要hive的sql中指定了order by,那么所有的数据都会到同一个reducer进行处理,不管有多少map,也不管文件有多少的block,只会启动一个reducer 。但是对于大量数据这将会消耗很长的时间去执行。

sort by是局部排序,每个reduce端都会进行排序,也就是局部有序,可以指定多个reduce。distribute by的功能是控制map结果的分发,它会将具有相同字段的map输出分发到一个reduce节点上做处理。某种情况下,我们需要控制某个特定行到某个reducer中,这种操作一般是为后续可能发生的聚集操作做准备。通常和sort by一起用,distribute by必须要写在sort by之前,理解成:按照XX字段分区,再按照XX字段排序。        当distribute by和sorts by字段相同时,可以使用cluster by方式代替。cluster by除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是升序排序,不能像distribute by一样去指定排序的规则为ASC或者DESC。

4.cluster_sample()

用户随机抽样。返回True表示该行数据被抽中。

  • 命令说明
  • cluster_sample(bigint <N>):表示随机抽取N条数据。
  • cluster_sample(bigint <N>, bigint <M>):表示按比例(M/N)随机抽取。即抽取partition_row_count×M / N条数据。partition_row_count指分区中的数据行数。
  • 参数说明
  • N:必填。BIGINT类型常量。N为NULL时,返回值为NULL。
  • M:必填。BIGINT类型常量。M为NULL时,返回值为NULL。
  • partition_clause:可选。
--随机抽取N条数据select  id,  det
from(select    id,    det,    cluster_sample(5) over() flag
from tb
) tmp
where flag =true;id  det
4   d
7   g
9   i
12  l
13  m
--按比例抽取 eg:20%select  id,  det
from(select    id,    det,    cluster_sample(5,1) over() flag
from tb
) tmp
where flag =true;id  det
3   c
11  k
20  t
22  v
26  z

2.数据块抽样(Hive)

tablesample语法MaxComouter不支持,这里介绍在hive中使用

注意:测试过程中发现,select语句不能带where条件且不支持子查询,可通过新建中间表或使用随机抽样解决(tablesample不支持子查询和where,可以另外建中间表,或者用临时表with as)

1.基于比例抽样

抽样的最小单元是一个HDFS数据块,一般一个HDFS数据块大小为128M

如果表的数据少于一个HDFS数据块的大小,那么会返回所有的数

--根据hive表数据的大小按比例抽取数据,例如:取10%。select*from tb tablesample(10 percent);

2.基于抽样数据的大小

如果抽样数据的大小N(tablesample(N))未达到一个HDFS块大小,会输出全部的记录

--单位为M,例如取10M大小数据。select*from tb tablesample(10M);

3.基于抽样数据的行数

tablesample(n rows) 指定抽样数据的行数,其中n代表每个map任务均取n行数据;对每个split的数据都n条数据

--其中n代表每个map任务均取n行数据,例如取10行数据select*from tb tablesample(10 rows);

3.分桶抽样(Hive)

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

1.基于随机抽样

--将tb表中的数据随机分为5个bucket,然后抽取编号为1的bucket的数据select*from tb tablesample(bucket 1 out of 5on rand());

2.基于字段列名抽样

--基于id列对tb表抽样,一个id一个bucket,这里抽取第一个bucket id的数据-- 如果表在创建时已经使用cluster by分桶,而且tablesample指定的列正是用于分桶的列,那么在抽样时,可以只涉及到表相应的hash分区的数据,而无需扫描整张表。因为表中的数据已经按列的hash值分割到不同的分区。select*from tb tablesample(bucket 1 out of 5on id);

4.分层抽样(ODPS/Hive)

分层抽一定数量可以使用开窗函数

1.row_number()

--针对每个id组,取组内3条数据select*from(select    id,    det,    row_number() over(partition by id orderby rand()) rn
from tb
) tmp
where rn <=5;

2.ntile()

--针对每个id组,对组内分5份数据,取每组第2份数据select*from(select    id,    det,    ntile(5) over(partition by id orderby rand()) nt
from tb
) tmp
where nt =2;

3.cluster_sample()

--针对每个id组,取每组5条数据select*from(select    id,    det,    cluster_sample(5) over(partition by id orderby rand()) cs
from tb
) tmp
where cs =true;

四、总结

以上就是关于抽样数据的使用介绍,当然实现的方式有很多种

1.TABLESAMPLE 抽样函数本身是不走MR 的所以执行速度很快(注意抽取多少M的时候,只能是整数M)

2.随机抽样函数需要走MR的,所以执行性能上没有TABLESAMPLE那么快,而且表达能力有限,只能获取特定的条数(limit n)

3.借助row_number实现分层抽样



相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
22天前
|
SQL JSON 数据库
influxdb 端点使用http进行sql查询,写数据
influxdb 端点使用http进行sql查询,写数据
66 0
|
1天前
|
SQL 关系型数据库 MySQL
解决:Mybatis-plus向数据库插入数据的时候 报You have an error in your SQL syntax
该博客文章讨论了在使用Mybatis-Plus向数据库插入数据时遇到的一个常见问题:SQL语法错误。作者发现错误是由于数据库字段中使用了MySQL的关键字,导致SQL语句执行失败。解决方法是将这些关键字替换为其他字段名称,以避免语法错误。文章通过截图展示了具体的操作步骤。
|
6天前
|
SQL 存储 分布式计算
|
11天前
|
SQL 物联网 数据处理
"颠覆传统,Hive SQL与Flink激情碰撞!解锁流批一体数据处理新纪元,让数据决策力瞬间爆表,你准备好了吗?"
【8月更文挑战第9天】数据时代,实时性和准确性至关重要。传统上,批处理与流处理各司其职,但Apache Flink打破了这一界限,尤其Flink与Hive SQL的结合,开创了流批一体的数据处理新时代。这不仅简化了数据处理流程,还极大提升了效率和灵活性。例如,通过Flink SQL,可以轻松实现流数据与批数据的融合分析,无需在两者间切换。这种融合不仅降低了技术门槛,还为企业提供了更强大的数据支持,无论是在金融、电商还是物联网领域,都将发挥巨大作用。
32 6
|
11天前
|
SQL 安全 数据处理
揭秘数据脱敏神器:Flink SQL的神秘力量,守护你的数据宝藏!
【8月更文挑战第9天】在大数据时代,Apache Flink以其强大的流处理能力脱颖而出,而Flink SQL则为数据处理带来了灵活性。本文介绍如何运用Flink SQL实现数据脱敏——一项关键的隐私保护技术。通过内置函数与表达式,在SQL查询中加入脱敏逻辑,可有效处理敏感信息,如个人身份与财务数据,以符合GDPR等数据保护法规。示例展示了如何对信用卡号进行脱敏,采用`CASE`语句检查并替换敏感数据。此外,Flink SQL支持自定义函数,适用于更复杂的脱敏需求。掌握此技能对于保障数据安全至关重要。
33 5
|
13天前
|
SQL 关系型数据库 MySQL
“震撼揭秘!Flink CDC如何轻松实现SQL Server到MySQL的实时数据同步?一招在手,数据无忧!”
【8月更文挑战第7天】随着大数据技术的发展,实时数据同步变得至关重要。Apache Flink作为高性能流处理框架,在实时数据处理领域扮演着核心角色。Flink CDC(Change Data Capture)组件的加入,使得数据同步更为高效。本文介绍如何使用Flink CDC实现从SQL Server到MySQL的实时数据同步,并提供示例代码。首先确保SQL Server启用了CDC功能,接着在Flink环境中引入相关连接器。通过定义源表与目标表,并执行简单的`INSERT INTO SELECT`语句,即可完成数据同步。
40 1
|
19天前
|
SQL 关系型数据库 数据库
|
24天前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
19天前
|
SQL 关系型数据库 数据库
|
20天前
|
SQL 存储 JSON
AlaSQL.js:用SQL解锁JavaScript数据操作的魔法
AlaSQL.js:用SQL解锁JavaScript数据操作的魔法
19 1