Spark SQL 桶抽样(Bucket Sampling)

目录

前言:

在Spark SQL中,桶抽样(Bucket Sampling)是一种基于哈希分桶的抽样方法,它可以将数据划分为若干个桶(bucket),然后抽取其中一个或多个桶的数据作为样本。桶抽样有两种主要形式:

基于分桶列(Bucketed Column)的抽样:这种抽样要求表本身是分桶表(Bucketed Table),并且抽样是基于分桶时指定的列进行的。

基于任意列的随机抽样:使用TABLESAMPLE语法,可以基于随机函数(如rand())或指定列进行分桶抽样,即使表不是分桶表也可以使用。

这里我们主要讨论第二种,即使用TABLESAMPLE (BUCKET x OUT OF y ON expr)语法,其中expr可以是列名,也可以是随机函数(如rand())。

语法:

sql 复制代码
SELECT ...
FROM table_name
TABLESAMPLE (BUCKET x OUT OF y [ON colname | rand()])

解释:

x:抽取的桶编号,从1开始。

y:总桶数。

ON后面的表达式:可以是某个列名,也可以是一个随机函数(如rand())。如果是列名,那么会根据该列的哈希值进行分桶抽样;如果是rand(),则使用随机分桶(每次运行不同,除非指定种子),如果使用rand(seed)则可以重复抽样。

注意:

桶抽样是精确抽样,它将数据分成y个桶,然后抽取第x个桶。

当使用列名进行分桶抽样时,具有相同列值的行会进入同一个桶,这样可以保证具有相同关键字的行被一起抽样或不被抽样。

当使用rand()时,则是随机将行分配到各个桶中,每次运行会因为随机性而不同。

示例:

示例1:基于某个列(如user_id)进行桶抽样,保证相同user_id的行在同一个桶中:

sql 复制代码
sql
SELECT * 
FROM sales 
TABLESAMPLE (BUCKET 1 OUT OF 10 ON user_id);

这将数据分成10个桶,然后抽取第1个桶的数据。同一个user_id的所有行都会被分到同一个桶中,因此要么全部被抽中,要么全部不被抽中。

示例2:基于随机函数进行桶抽样(每次运行结果随机):

sql 复制代码
sql
SELECT * 
FROM sales 
TABLESAMPLE (BUCKET 1 OUT OF 10 ON rand());

同样分成10个桶,抽取第1个桶,但是行是随机分配的。

示例3:可重复的随机抽样(通过指定随机种子):

sql 复制代码
sql
SELECT * 
FROM sales 
TABLESAMPLE (BUCKET 1 OUT OF 10 ON rand(42));

这样,每次运行都会得到相同的抽样结果。

示例4:抽取多个桶:例如,抽取前3个桶(即30%的数据):

使用WHERE子句配合取模运算(前提是抽样表达式相同):

sql 复制代码
sql
SELECT *
FROM (
    SELECT *, abs(hash(rand(42))) % y AS bucket_id
    FROM sales
) tmp
WHERE bucket_id IN (0, 1, 2);   -- 注意:桶的编号在0到y-1之间?

但是要注意,TABLESAMPLE的分桶编号是从1开始,而自己计算哈希取模通常是0到y-1。所以需要调整。

相关推荐
麦聪聊数据7 小时前
企业数据流通与敏捷API交付实战(五):异构数据跨库联邦与零代码发布
数据库·sql·低代码·restful
生瓜硬劈..9 小时前
SQL 调优全解:从 20 s 到 200 ms 的 6 步实战笔记
java·笔记·sql
颜颜yan_9 小时前
让数据库学会说“不“——金仓 SQL 防火墙深度解析
数据库·sql
霖霖总总9 小时前
[小技巧52]从 SQL 到结果:MySQL 8.0 查询执行全流程深度剖析
sql·mysql
輕華9 小时前
【零基础入门】SQL 核心语法精讲:外键约束与多表查询全解析(进阶篇)
数据库·sql
white-persist11 小时前
【渗透测试 红队】Netcat(NC)渗透实战全指南详解
开发语言·数据库·python·sql·算法·web安全·网络安全
麦聪聊数据13 小时前
企业数据流通与敏捷API交付实战(四):DaaS与SQL2API
数据库·sql·低代码·restful
lingggggaaaa15 小时前
PHP原生开发篇&SQL注入&数据库监控&正则搜索&文件定位&静态分析
数据库·sql·安全·web安全·php
夫礼者17 小时前
【极简监控】选连接池送深度监控?用 Druid 补齐单体应用全局 SQL 统计的最后拼图
java·数据库·sql·druid
码农学院18 小时前
一些在平常开发过程中会用到的比较经典的 SQL 语句,常常用于实现一些很特别的功能。
数据库·sql