前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >复习 | HIVE 随机采样②

复习 | HIVE 随机采样②

作者头像
Spark学习技巧
发布2018-08-30 16:28:46
1.1K0
发布2018-08-30 16:28:46
举报
文章被收录于专栏:Spark学习技巧Spark学习技巧

前面一篇文章,三种采样机制的其中一种

复习:聊聊hive随机采样①

今天将剩下的两种,分桶采样数据块采样

当数据量特别大时,对全体数据进行处理存在困难时,抽样就显得尤其重要了。抽样可以从被抽取的数据中估计和推断出整体的特性,是科学实验、质量检验、社会调查普遍采用的一种经济有效的工作和研究方法。

Hive支持桶表抽样和块抽样,下面分别学习。所谓桶表指的是在创建表时使用CLUSTERED BY子句创建了桶的表。桶表抽样的语法如下:

代码语言:javascript
复制
table_sample: TABLESAMPLE (BUCKET x OUT OF y [ON colname])

TABLESAMPLE子句允许用户编写用于数据抽样而不是整个表的查询,该子句出现FROM子句中,可用于任何表中。桶编号从1开始,colname表明抽取样本的列,可以是非分区列中的任意一列,或者使用rand()表明在整个行中抽取样本而不是单个列。在colname上分桶的行随机进入1到y个桶中,返回属于桶x的行。下面的例子中,返回32个桶中的第3个桶中的行:

代码语言:javascript
复制
SELECT *
FROM source TABLESAMPLE(BUCKET 3 OUT OF 32 ON rand()) s;

通常情况下,TABLESAMPLE将会扫描整个表然后抽取样本,显然这种做法效率不是很高。替代方法是,由于在使用CLUSTERED BY时指定了分桶的列,如果抽样时TABLESAMPLE子句中指定的列匹配CLUSTERED BY子句中的列,TABLESAMPLE只扫描表中要求的分区。假如上面的例子中,source表在创建时使用了CLUSTEREDBY id INTO 32 BUCKETS,那么下面的语句将返回第3个和第19个簇中的行,因为每个桶由(32/16)=2个簇组成。为什么是3和19呢,因为要返回的是第3个桶,而每个桶由原来的2个簇组成,第3个桶就由原来的第3个和19个簇组成,根据简单的哈希算法(3%16=19%16)。

代码语言:javascript
复制
TABLESAMPLE(BUCKET 3 OUT OF 16 ON id)

相反,下面的语句将会返回第3个簇的一半,因为每个桶由(32/64)=1/2个簇组成。

代码语言:javascript
复制
TABLESAMPLE(BUCKET 3 OUT OF 64 ON id)

从Hive-0.8开始可以使用块抽样,语法为:

代码语言:javascript
复制
block_sample: TABLESAMPLE (n PERCENT)

该语句允许抽取数据大小的至少n%(不是行数,而是数据大小)做为输入,支持CombineHiveInputFormat而一些特殊的压缩格式是不能够被处理的,如果抽样失败,MapReduce作业的输入将是整个表。由于在HDFS块层级进行抽样,所以抽样粒度为块的大小,例如如果块大小为256MB,即使输入的n%仅为100MB,也会得到256MB的数据。下面的例子中输入的0.1%或更多将用于查询:

代码语言:javascript
复制
SELECT *
FROM source TABLESAMPLE(0.1 PERCENT) s;

如果希望在不同的块中抽取相同的数据,可以改变下面的参数:

代码语言:javascript
复制
set hive.sample.seednumber=<INTEGER>;

也可以指定读取数据的长度,该方法与PERCENT抽样具有一样的限制,为什么有相同的限制,是因为该语法仅将百分比改为了具体值,但没有改变基于块抽样这一前提条件。该语法为:

代码语言:javascript
复制
block_sample: TABLESAMPLE (ByteLengthLiteral)
 
ByteLengthLiteral : (Digit)+ ('b' | 'B' | 'k' | 'K' | 'm' | 'M' | 'g' | 'G')

下面的例子中输入的100M或更多将用于查询:

代码语言:javascript
复制
SELECT *
FROM source TABLESAMPLE(100M) s;

Hive也支持基于行数的输入限制,当效果与上面介绍的两个不同。首先不需要CombineHiveInputFormat,这意味着可以被用在非原生表中。其次行数被用在每个split中。因此总的行数根据输入的split数而变化很大。语法格式为:

代码语言:javascript
复制
block_sample: TABLESAMPLE (n ROWS)

例如下面的查询将从每个split中抽取10行:

代码语言:javascript
复制
SELECT * FROM source TABLESAMPLE(10 ROWS);

更多大数据知识,大数据学习技巧,spark 调优,源码等,欢迎加入知识星球

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 浪尖聊大数据 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档