hive 随机抽样

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,看结果:

Hive sampling

结果差不多是源表记录的1/20,Hive在运行时候,会在第一个桶中抽样一半的数据。

还有一点:

如果从源表中直接分桶抽样,也能达到一样的效果,比如:

SELECT COUNT(1) FROM lxw1 TABLESAMPLE(BUCKET 1 OUT OF 20 ON pcid);

区别在于基于已经分桶的表抽样,查询只会扫描相应桶中的数据,而基于未分桶表的抽样,查询时候需要扫描整表数据,先分桶,再抽样。

 
文章转自:http://lxw1234.com/archives/2015/08/444.htm
 

猜你喜欢

转载自daizj.iteye.com/blog/2273426