【问题标题】:Data Sampling based on a field基于字段的数据采样
【发布时间】:2012-03-20 23:22:00
【问题描述】:

我想根据时间戳字段对数据进行采样。我正在阅读巨大的数据文件,每个文件每天都有近百万条记录。我每个月都有几个这样的文件。

现在我想读取这些数据,但仅将 5% 或 10% 存储到 mysql 数据库中。我不知道每个数据文件中的记录数量。

有什么方法可以只对文件的总读取数据进行 5% 的采样?这类问题有什么标准的统计方法吗?

根据以下 cmets 进行编辑:

在这个采样想法之前,我已经在两个字段上创建了一个基于键的分区和索引:id 和 date。 id 字段更像是一个 clientId。即使使用分区,在 1500 万行上按 2 个字段分组也会花费很长时间,在 30 到 60 分钟的范围内。我还按字段在其中一个分组上创建了附加索引。

我的解释是这样的:

SIMPLE 访问 ref 3ColumnerIndex,2ColumnIndex 2ColumnIndex 302 const 7493642 using where;使用文件排序

在为 innodb 提供 4 GB 的缓冲区大小后获得了这种性能!

【问题讨论】:

  • 在文件中,每条记录是单独一行还是以某种方式包含?
  • 是的,每条记录都是一行。我在我的 java 代码中读取该文件并进行清理、解析等。这不是问题,我可以读取所有文件,甚至可以将其全部写入数据库,但是将所有数据写入一个月让我关闭到 15-20 百万条记录。
  • 那么,读完文件,你知道你读了多少条记录吗?
  • 这不是统计问题吗? :) 您可能需要评估您的数据以了解应该如何收集样本,您的样本可能与总数据不符
  • 不,我一次读一行。读完一行后,我需要根据我的样本大小做出决定将其写入数据库

标签: java mysql statistics sampling


【解决方案1】:

您需要估计记录数才能使其工作,但如果您对需要多少样本没有严格要求,这应该不是问题:

  1. 假设您从n 记录中选择k 样本。
  2. 对于每条记录,或者直到您有足够的记录:
    1. 产生一个介于 0 和 1 之间的随机数。
    2. 如果小于k/n,则输出当前记录。输入k := k-1n := n-1
    3. 否则,丢弃记录并输入n := n-1

每条记录以概率 k/n 出现在输出中。例如。第二条记录出现的概率为:

(k/n)*(k-1)/(n-1) + ((n-k)/n)*k/(n-1) = (k-1+n-k)*k/(n*(n-1)) = k/n

【讨论】:

  • 感谢您的回答。我看到了这个世界是如何工作的。我事先没有 n。
  • 您可以“猜测” n 和 k 作为输入文件大小的一部分。如果你弄错了,要么某些记录被选中的可能性比其他记录小,要么你得到的输出记录少于 k 个。根据您生成 5-10% 的随机样本的要求,这应该没问题。
  • 你可以做的另一件事是将生成的随机数与一个恒定的百分比进行比较,但是输出记录的数量具有一定的随机性。或者,您可以使用此算法从 10000 条记录中的每个块中选择 500 条记录,但由于某些组合比其他组合更有可能,输出会出现一些偏差。
  • 我同意,我在考虑文件大小。谢谢,现在应该足够了:-)
【解决方案2】:

你可以像这样使用 Limit

SELECT name, email FROM users WHERE name LIKE 'a%' LIMIT 10;

但我也发现这个链接可能会更具体地帮助你

http://www.gloomy.eu/mysql-desired-percentage-of-rows/

【讨论】:

  • 这将只返回查询的前 N ​​条记录,由一些半随机数据库排序定义。这远非抽样。
猜你喜欢
  • 2018-07-03
  • 1970-01-01
  • 2023-03-23
  • 2017-05-28
  • 2020-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多