对于大型数据库,从 Impala 中抽样的最佳查询是什么?
What is the best query to sample from Impala for a huge database?
我在 Impala 中有一个巨大的 table(超过 10 亿行)。我需要多次采样 ~ 100,000 行。查询示例行的最佳方式是什么?
不幸的是,Impala 目前不支持 TABLESAMPLE。请参阅 https://issues.cloudera.org/browse/IMPALA-1924 以了解其发展。
正如 Jeff 所提到的,您所要求的完全不可能,但我们确实有一个内部聚合函数,它需要 200,000 个样本(使用水库抽样)和 returns 个样本,逗号-定界为单行。目前还无法更改样本数量。如果少于 200,000 行,则全部返回。如果您对其工作原理感兴趣,请参阅 implementation of the aggregate function and reservoir sampling structures.
也没有办法 'split' 或分解结果,所以我不知道这会有多大帮助。
例如,从具有 8 行的 table 中简单抽样:
> select sample(id) from functional.alltypestiny
+------------------------+
| sample(id) |
+------------------------+
| 0, 1, 2, 3, 4, 5, 6, 7 |
+------------------------+
Fetched 1 row(s) in 4.05s
(上下文:这是在过去的版本中添加的,以支持规划器中的直方图统计,不幸的是,它还没有准备好。)
回过头来看,知道TABLESAMPLE是不可用的,可以在每条记录中添加一个字段"RVAL"(例如32位随机整数),并通过添加"where RVAL > x and RVAL < y"重复采样,对于x 和 y 的适当值。非重叠区间 [x1,y1]、[x2,y2]... 将是独立的。您还可以 select 使用“where RVAL%10000 = 1, =2, ... 等,用于单独的独立子集群。
其他答案中提到的 TABLESAMPLE 现在在 impala (>=2.9.0) 的较新版本中可用,请参阅 documentation。
下面是一个示例,说明如何使用它对 1% 的数据进行采样:
SELECT foo FROM huge_table TABLESAMPLE SYSTEM(1)
或
SELECT bar FROM huge_table TABLESAMPLE SYSTEM(1) WHERE name='john'
看起来 percentage
参数必须是整数,因此您可以采用的最小样本限制为 1%。
请记住,来自 table 的采样数据的比例无法保证,可能会大于指定的百分比(在本例中大于 1%)。这在 Impala 的文档中有更详细的解释。
如果您正在寻找特定列的样本,您可以查看以下答案。
比如说,你有全球数据,你想从中随机挑选 10% 并创建你的数据集。您也可以使用任意列组合 - 例如城市、邮政编码和州。
select * from
(
select
row_number() over (partition by country order by country , random()) rn,
count() over (partition by country order by country) cntpartition,
tab.*
from dat.mytable tab
)rs
where rs.rn between 1 and cntpartition* 10/100 -- This is for 10% data
Link -
Randomly sampling n rows in impala using random() or tablesample system()
我在 Impala 中有一个巨大的 table(超过 10 亿行)。我需要多次采样 ~ 100,000 行。查询示例行的最佳方式是什么?
Impala 目前不支持 TABLESAMPLE。请参阅 https://issues.cloudera.org/browse/IMPALA-1924 以了解其发展。
正如 Jeff 所提到的,您所要求的完全不可能,但我们确实有一个内部聚合函数,它需要 200,000 个样本(使用水库抽样)和 returns 个样本,逗号-定界为单行。目前还无法更改样本数量。如果少于 200,000 行,则全部返回。如果您对其工作原理感兴趣,请参阅 implementation of the aggregate function and reservoir sampling structures.
也没有办法 'split' 或分解结果,所以我不知道这会有多大帮助。
例如,从具有 8 行的 table 中简单抽样:
> select sample(id) from functional.alltypestiny
+------------------------+
| sample(id) |
+------------------------+
| 0, 1, 2, 3, 4, 5, 6, 7 |
+------------------------+
Fetched 1 row(s) in 4.05s
(上下文:这是在过去的版本中添加的,以支持规划器中的直方图统计,不幸的是,它还没有准备好。)
回过头来看,知道TABLESAMPLE是不可用的,可以在每条记录中添加一个字段"RVAL"(例如32位随机整数),并通过添加"where RVAL > x and RVAL < y"重复采样,对于x 和 y 的适当值。非重叠区间 [x1,y1]、[x2,y2]... 将是独立的。您还可以 select 使用“where RVAL%10000 = 1, =2, ... 等,用于单独的独立子集群。
其他答案中提到的 TABLESAMPLE 现在在 impala (>=2.9.0) 的较新版本中可用,请参阅 documentation。
下面是一个示例,说明如何使用它对 1% 的数据进行采样:
SELECT foo FROM huge_table TABLESAMPLE SYSTEM(1)
或
SELECT bar FROM huge_table TABLESAMPLE SYSTEM(1) WHERE name='john'
看起来 percentage
参数必须是整数,因此您可以采用的最小样本限制为 1%。
请记住,来自 table 的采样数据的比例无法保证,可能会大于指定的百分比(在本例中大于 1%)。这在 Impala 的文档中有更详细的解释。
如果您正在寻找特定列的样本,您可以查看以下答案。
比如说,你有全球数据,你想从中随机挑选 10% 并创建你的数据集。您也可以使用任意列组合 - 例如城市、邮政编码和州。
select * from
(
select
row_number() over (partition by country order by country , random()) rn,
count() over (partition by country order by country) cntpartition,
tab.*
from dat.mytable tab
)rs
where rs.rn between 1 and cntpartition* 10/100 -- This is for 10% data
Link - Randomly sampling n rows in impala using random() or tablesample system()