数据集太大,无法加载到内存中进行处理

时间:2012-04-09 21:10:04

标签: mysql ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.2

我有一个大约400万行的快速增长的数据集,以便定义和排除异常值(用于统计/分析用法)我需要算法来考虑此数据集中的所有条目。然而,这是太多的数据加载到内存和我的系统窒息。我目前正在使用它来收集和处理数据:

@scoreInnerFences = innerFence Post.where( :source => 1 ).
                                    order( :score ).
                                    pluck( :score )

使用典型的分治方法是行不通的,我不认为因为每个条目都必须考虑让我的异常计算准确。如何有效地实现这一目标?

innerFence标识数据集的下四分位数和上四分位数,然后使用这些结果来计算异常值。这是(尚未重构,非DRY)代码:

def q1(s)
  q = s.length / 4

  if s.length % 2 == 0
    return ( s[ q ] + s[ q - 1 ] ) / 2
  else
    return s[ q ]
  end
end

def q2(s)
  q = s.length / 4

  if s.length % 2 == 0
    return ( s[ q * 3 ] + s[ (q * 3) - 1 ] ) / 2
  else
    return s[ q * 3 ]
  end
end

def innerFence(s)
  q1 = q1(s)
  q2 = q2(s)

  iq = (q2 - q1) * 3

  if1 = q1 - iq
  if2 = q2 + iq

  return [if1, if2]
end

2 个答案:

答案 0 :(得分:1)

这不是最好的方法,但这是一种简单的方法:

做几个查询。首先计算分数:

q = Post.where(:source => 1).count

然后你做你的计算 然后你取得分数

q1 = Post.where(:source => 1)。 reverse_order(:得分)。 选择(“平均(得分)为分数”)。 偏移量(Q).limit((Q%2)+1)

q2 = Post.where(:source => 1)。 reverse_order(:得分)。 选择(“平均(得分)为分数”)。 偏移量(Q * 3).limit((Q%2)+1)

代码可能不对,但我相信你明白了。

答案 1 :(得分:0)

对于大型数据集,我有时会下载到ActiveRecord下面。这是一个记忆力,即使我想象,使用采摘。当然它的便携性较差,但有时值得。

得分= Post.connection.execute('从得分>按分数排序1的帖子中选择得分')。map(&:first)

不知道这对400万的记录是否有足够的帮助。如果没有,也许看一下存储过程?