使用 random() 或 tablesample system() 在 impala 中随机采样 n 行

Posted

技术标签:

【中文标题】使用 random() 或 tablesample system() 在 impala 中随机采样 n 行【英文标题】:Randomly sampling n rows in impala using random() or tablesample system() 【发布时间】:2021-07-05 16:09:04 【问题描述】:

我想使用 Impala 从表中随机抽取 n 行。我可以想到两种方法来做到这一点,即:

SELECT * FROM TABLE ORDER BY RANDOM() LIMIT <n>

SELECT * FROM TABLE TABLESAMPLE SYSTEM(1) limit <n>

在我的例子中,我将 n 设置为 10000,并从超过 2000 万行的表中进行抽样。如果我理解正确,第一个选项本质上为每行创建一个介于 0 和 1 之间的随机数,并按此随机数排序。 第二个选项创建许多不同的“桶”,然后随机抽取至少 1% 的数据(实际上这似乎总是比提供的百分比大得多)。在这两种情况下,我只选择前 10000 行。

在我的案例中,随机抽样 10K 行的第一个选项可靠吗?

编辑:一些额外的上下文。数据的结构就是为什么整个表的随机抽样或洗牌对我来说似乎很重要。每天都会向表中添加额外的行。例如,其中一列是country,通常传入的行首先来自国家 A,然后来自国家 B,等等。因此,我担心第二个选项可能会从一个单一的行中采样太多行国家,而不是随机的。这是一个合理的担忧吗?

揭示第二个选项的相关线程:What is the best query to sample from Impala for a huge database?

【问题讨论】:

如果您有像您想要处理的国家/地区这样的名义分布,请尝试进行分层抽样而不是纯随机抽样。 【参考方案1】:

我请求不同的 OP。我更喜欢第二个选项。 第一个选项,您为所有数据分配值 0 到 1,然后选取前 10000 条记录。所以基本上,impala 必须处理表中的所有行,因此如果你有一个 2000 万行的表,操作会很慢。 第二种选择,impala 根据您提供的百分比从文件中随机选取行。由于这适用于文件,因此返回的行数可能与您提到的百分比不同。此外,此方法用于计算 Impala 中的统计信息。因此,在性能方面这要好得多,并且随机的正确性可能是一个问题。

最后的想法- 如果您担心随机数据的随机性和正确性,请选择选项 1。但如果您不太担心随机性并且想要样本数据和快速性能,请选择第二个选项。由于 Impala 将其用于 COMPUTE STATS,因此我选择了这个 :)

编辑:查看您的要求后,我有一种方法可以对特定字段或字段进行采样。

我们将使用窗口函数为每个国家组随机设置行号。然后从该数据集中选取 1% 或任何你想选取的 %。 这将确保您的数据在国家/地区之间均匀分布,并且每个国家/地区在结果数据集中具有相同百分比的行。

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* 1/100  -- This is for 1% data

我的数据截图 -

HTH

【讨论】:

我用更多的上下文编辑了这个问题,解释了为什么随机性部分对我很重要,以及我从中采样的数据是如何结构化的。你还会选择第二个选项吗? 我想我找到了适合你的解决方案...它将对国家数据进行抽样。

以上是关于使用 random() 或 tablesample system() 在 impala 中随机采样 n 行的主要内容,如果未能解决你的问题,请参考以下文章

sql MS SQL TABLESAMPLE

HiveSql抽样

分析表语法错误

通过 SQLAlchemy 获取随机行

HIVE数据抽样

【Hive】数据抽样