HIVE基本查询操作(二)——第3关:Hive抽样查询

简介: HIVE基本查询操作(二)——第3关:Hive抽样查询

任务描述

本关任务:计算每个股票每天的总交易量。


相关知识

为了完成本关任务,你需要掌握:1.随机抽样 2.桶表抽样 3.数据块抽样


随机抽样

使用RAND()函数和LIMIT关键字来获取样例数据,使用DISTRIBUTESORT关键字来保证数据是随机分散到mapperreducer的。ORDER BY RAND()语句可以获得同样的效果,但是性能没这么高。

/**从table表里随机抽取5行数据*/
//第一种:
SELECT * FROM table DISTRIBUTE BY RAND() SORT BY RAND() LIMIT 2;
//第二种(性能不太好):
SELECT * FROM table ORDER BY RAND() LIMIT 2;


桶表抽样

*Hive分桶*

对于每一个表(table)或者分区, Hive 可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive 也是 针对某一列进行桶的组织。Hive 采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。


桶(bucket)是指将表或分区中指定列的值为key进行hashhash到指定的桶中,这样可以支持高效采样工作。


把表(或者分区)组织成桶(Bucket)有两个理由:

获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
//创建一个分桶表(CLUSTERED BY 子句来指定划分桶所用的列和要划分的桶的个数)
create table bucket_user (
  id int,
  name string
)clustered by(id) into 4 buckets
row format delimited fields terminated by '\t'
stored as textfile;
//在这里,我们使用用户ID来确定如何划分桶(Hive使用对值进行哈希并将结果除 以桶的个数取余数)。


配置所需环境(必须):

要向分桶表中填充成员,需要将 hive.enforce.bucketing 属性设置为 true。①这 样,Hive 就知道用表定义中声明的数量来创建桶。然后使用 INSERT 命令即可。需要注意的是: clustered by和sorted by不会影响数据的导入,这意味着,用户必须自己负责数据如何如何导入,包括数据的分桶和排序
'set hive.enforce.bucketing = true' 可以自动控制上一轮reduce的数量从而适配bucket的个数,当然,用户也可以自主设置mapred.reduce.tasks去适配bucket个数,推荐使用'set hive.enforce.bucketing = true'


桶表抽样

select * from table_name tablesample(bucket X out of Y on field);
//X:从哪个桶开始抽取  Y:相隔几个桶后再次抽取  field:列名 注意:x的值必须小于等于y的值
//示例:bkt表(总共30个桶)
select * from bkt tablesample(bucket 2 out of 6 on id)
//表示从桶中抽取5(30/6)个bucket数据,从第2个bucket开始抽取,抽取的个数由每个桶中的数据量决定。相隔6个桶再次抽取,因此,依次抽取的桶为:2,8,14,20,26


数据块抽样

该方式允许 Hive 随机抽取N行数据,数据总量的百分比(n百分比)或N字节的数据。

//抽取table表中50%的数据
SELECT * FROM table TABLESAMPLE (50 PERCENT);
//抽取table表中30m的数据
SELECT * FROM table TABLESAMPLE (30M);
//根据数据行数来取样
SELECT * FROM table TABLESAMPLE (200 ROWS);
//这种方式可以根据行数来取样,但要特别注意:这里指定的行数,是在每个InputSplit中取样的行数,也就是,每个Map中都取样n ROWS。
如果有3个Map Task(InputSplit),每个取200行,总共600行


编程要求

根据提示,在右侧编辑器补充代码,计算每个股票每天的交易量。

  1. 采用桶表抽样的方法(从第二个桶开始抽样,每隔两个开始抽样);
  2. 创建分桶表total_bucket(以股票ID进行分桶,共分为 6 个桶);
  3. 数据从total表获取。


表名:total

col_name data_type comment
tradedate string 交易日期
tradetime string 交易时间
securityid string 股票ID
bidpx1 string 买入价
bidsize1 int 买入量
offerpx1 string 卖出价
bidsize2 int 卖出量


部分数据如下所示:

20130724    145004    152896    2.62    6960    2.63    13000
20130724    145101    152896    2.86    13880    2.89    6270
20130724    145128    152896    2.85    327400    2.851    1500
20130724    145143    152896    2.603    44630    2.8    10650


数据说明:

(152896: 每种股票id)
(20130724: 2013年7月24日)
(145004: 14点50分04秒)


测试说明

平台会对你编写的代码进行测试:

预期输出:

交易日期 股票id 总交易量

20130722    125896    33823300
20130722    204001    24830700
20130722    412233    249769380
20130722    553211    742712700
20130722    745962    90592600
20130722    856947    161685600
20130723    204001    77617900
20130723    869547    258300900
20130724    152896    13158580
20130724    204001    48889500
20130724    745896    199706260
20130724    856974    14958220
20130724    881125    246118000
20130725    125896    1584560
20130725    425178    1286900
20130725    668452    1416400
20130725    745962    874720
20130725    789562    4073430
20130725    968956    508900
20130726    204001    263772500


----------禁止修改----------
create database if not exists mydb;
use mydb;
create table if not exists total(
tradedate string,
tradetime string,
securityid string,
bidpx1 string,
bidsize1 int,
offerpx1 string,
bidsize2 int)
row format delimited fields terminated by ','
stored as textfile;
truncate table total;
load data local inpath '/root/files' into table total;
drop table if exists total_bucket;
----------禁止修改----------
----------begin----------
---------- 创建分桶 ----------
create table if not exists total_bucket (
    tradedate string,
    securityid string,
    bidsize1 int,
    bidsize2 int
)clustered by(securityid) into 6 buckets
row format delimited fields terminated by ','
stored as textfile;
set hive.enforce.bucketing = true;
insert overwrite table total_bucket
select tradedate, securityid, bidsize1, bidsize2
from total;
select tradedate, securityid, sum(bidsize1 + bidsize2)
from total_bucket tablesample(bucket 2 out of 2 on securityid)
group by tradedate, securityid;
----------end----------


目录
相关文章
|
7月前
|
SQL Java 数据库连接
java链接hive数据库实现增删改查操作
java链接hive数据库实现增删改查操作
428 0
|
SQL Java 数据库连接
Hive教程(08)- JDBC操作Hive
Hive教程(08)- JDBC操作Hive
891 0
|
SQL 存储 分布式计算
Hive的简单操作
Hive的简单操作
66 0
|
SQL 缓存 分布式计算
54 Hive的Join操作
54 Hive的Join操作
152 0
|
SQL HIVE
53 Hive的SELECT操作
53 Hive的SELECT操作
68 0
|
SQL 存储 分布式数据库
【通过Hive清洗、处理和计算原始数据,Hive清洗处理后的结果,将存入Hbase,海量数据随机查询场景从HBase查询数据 】
【通过Hive清洗、处理和计算原始数据,Hive清洗处理后的结果,将存入Hbase,海量数据随机查询场景从HBase查询数据 】
268 0
|
7月前
|
SQL 分布式计算 数据库
【大数据技术Spark】Spark SQL操作Dataframe、读写MySQL、Hive数据库实战(附源码)
【大数据技术Spark】Spark SQL操作Dataframe、读写MySQL、Hive数据库实战(附源码)
278 0
|
2月前
|
SQL 分布式计算 Hadoop
Hadoop-14-Hive HQL学习与测试 表连接查询 HDFS数据导入导出等操作 逻辑运算 函数查询 全表查询 WHERE GROUP BY ORDER BY(一)
Hadoop-14-Hive HQL学习与测试 表连接查询 HDFS数据导入导出等操作 逻辑运算 函数查询 全表查询 WHERE GROUP BY ORDER BY(一)
49 4
|
2月前
|
SQL
Hadoop-14-Hive HQL学习与测试 表连接查询 HDFS数据导入导出等操作 逻辑运算 函数查询 全表查询 WHERE GROUP BY ORDER BY(二)
Hadoop-14-Hive HQL学习与测试 表连接查询 HDFS数据导入导出等操作 逻辑运算 函数查询 全表查询 WHERE GROUP BY ORDER BY(二)
41 2
|
5月前
|
SQL 关系型数据库 MySQL
实时计算 Flink版操作报错合集之从mysql读数据写到hive报错,是什么原因
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。