概述
当数据量特别大时,我们可能需要获取一些数据的子集来加速数据分析。这就是采样,一种用于识别和分析数据子集以发现整个数据集中的模式和趋势的技术。在HQL中,采样数据有三种方式:随机采样、桶表采样和块采样。
随机采样
随机采样是使用rand() 函数和LIMIT关键字来获取数据的样本。如下示例,关键字 DISTRIBUTE 和 SORT 用以确保数据在mapper和reducer之间也是随机分布的。ORDER BY rand()语句也可以达到同样的目的,但是性能不好:
> SELECT name FROM employee_hr DISTRIBUTE BY rand() SORT BY rand() LIMIT 2;
+----------+
| name |
+----------+
| Will |
| Michael |
+----------+
桶表采样
桶表采样是一种特殊的采样方式,针对桶表进行了优化,如下示例。SELECT子句指定采样数据的列。在对整行进行采样时,也可以使用rand()函数。如果采样列同时也是CLUSTERED BY列,那么采样的效率会更高。桶表采样的语法如下:
table_sample: TABLESAMPLE (BUCKET x OUT OF y [ON colname])
示例:based on whole row
SELECT name FROM employee_trans TABLESAMPLE(BUCKET 1 OUT OF 2 ON rand()) a;
+-------+
| name |
+-------+
| Will |
+-------+
示例:based on bucket column
> SELECT name FROM employee_trans TABLESAMPLE(BUCKET 1 OUT OF 2 ON emp_id) a;
+-------+
| name |
+-------+
| Will |
+-------+
块采样
这种方式的采样允许查询随机提取n行数据、数据大小的百分之n 或数据的n字节。采样粒度是HDFS的块大小。示例如下:
示例:按行采样
> SELECT name FROM employee TABLESAMPLE(1 ROWS) a;
+----------+
| name |
+----------+
| Michael |
+----------+
示例:按数据大小的百分比采样
> SELECT name FROM employee TABLESAMPLE(50 PERCENT) a;
+----------+
| name |
+----------+
| Michael |
+----------+
示例:按数据大小采样
支持的单位有b/B, k/K, m/M, g/G
> SELECT name FROM employee TABLESAMPLE(3b) a;
+----------+
| name |
+----------+
| Michael |
+----------+
参考
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Sampling
书籍 Apache Hive Essentials Second Edition (by Dayong Du) Chapter 6