hive 随机抽样
程序员文章站
2022-06-23 20:49:48
...
1. Random sampling
使用RAND()函数和LIMIT关键字来获取样例数据。使用DISTRIBUTE和SORT关键字来保证数据是随机分散到mapper和reducer的。ORDER BY RAND()语句可以获得同样的效果,但是性能没这么高。
--Syntax:
SELECT * FROM <Table_Name> DISTRIBUTE BY RAND() SORT BY RAND() LIMIT <N rows to sample>;
2. Bucket table sampling
该方式是最佳化采样bucket表。RAND()函数也可以用来采样整行。如果采样列同时使用了CLUSTERED BY,使用TABLESAMPLE语句会更有效率。
--Syntax:
SELECT * FROM <Table_Name> TABLESAMPLE(BUCKET <specified bucket number to sample> OUT OF <total number of buckets> ON [colname|RAND()]) table_alias;
1) 使用下面的语句,从表lxw111中取样50%的数据,创建一个新表:
CREATE TABLE lxw1234 AS
SELECT * FROM lxw1 TABLESAMPLE (50 PERCENT);
2) 这种方式指定取样数据的大小,单位为M。比如,下面的语句:
SELECT * FROM lxw1 TABLESAMPLE (30M);
3) 这种方式可以根据行数来取样,但要特别注意:这里指定的行数,是在每个InputSplit中取样的行数,也就是,每个Map中都取样n ROWS。
SELECT * FROM lxw1 TABLESAMPLE (200 ROWS)
4) table_sample: TABLESAMPLE (BUCKET x OUT OF y [ON colname])
如果基于一个已经分桶表进行取样,将会更有效率。
执行下面的语句,创建一个分桶表,并插入数据:
CREATE TABLE lxw1_bucketed (pcid STRING)
CLUSTERED BY(pcid) INTO 10 BUCKETS;
INSERT overwrite TABLE lxw1_bucketed
SELECT pcid FROM lxw1;
表lxw1_bucketed按照pcid字段分成10个桶,下面的语句表示从10个桶中抽样第一个桶的数据:
SELECT COUNT(1) FROM lxw1_bucketed TABLESAMPLE(BUCKET 1 OUT OF 10 ON pcid);
很好理解。
再看这个:
SELECT COUNT(1) FROM lxw1_bucketed TABLESAMPLE(BUCKET 1 OUT OF 20 ON pcid)
表只有10个桶,如果指定20,看结果:
结果差不多是源表记录的1/20,Hive在运行时候,会在第一个桶中抽样一半的数据。
还有一点:
如果从源表中直接分桶抽样,也能达到一样的效果,比如:
SELECT COUNT(1) FROM lxw1 TABLESAMPLE(BUCKET 1 OUT OF 20 ON pcid);
区别在于基于已经分桶的表抽样,查询只会扫描相应桶中的数据,而基于未分桶表的抽样,查询时候需要扫描整表数据,先分桶,再抽样。
文章转自:http://lxw1234.com/archives/2015/08/444.htm