使用Ruby,如何将集合传递给方法,而不是它的子集?

使用Ruby,如何将集合传递给方法,而不是它的子集?,ruby,collections,Ruby,Collections,我有一组用户: users = User.all() 我想将用户集合的子集传递给一个方法。 每个子集应包含1000个项目(在上一次迭代中不超过1000个) 假设用户有9500项,我想调用一些方法10次,9次传递1000项,最后一次传递500项。我认为,您应该手动划分子集。 比如说, some_method(users[0..999]) 我认为,您应该手动划分子集。 比如说, some_method(users[0..999]) 您可以使用以下方法: 但这将首先从数据库中提取所有记录 但是,

我有一组用户:

users = User.all()
我想将用户集合的子集传递给一个方法。 每个子集应包含1000个项目(在上一次迭代中不超过1000个)


假设用户有9500项,我想调用一些方法10次,9次传递1000项,最后一次传递500项。

我认为,您应该手动划分子集。 比如说,

some_method(users[0..999])

我认为,您应该手动划分子集。 比如说,

some_method(users[0..999])
您可以使用以下方法:

但这将首先从数据库中提取所有记录

但是,我想你可以这样做:

def ar_each_slice scope, size
  (scope.count.to_f / size).ceil.times do |i|
    yield scope.scoped(:offset => i*size, :limit => size)
  end
end
并将其用作:

ar_each_slice(User.scoped, 1000) do |slice|
  some_method slice.all
end
它将首先获取记录数(使用COUNT),然后使用LIMIT子句获取1000 x 1000,并将其传递给您的块。

您可以使用以下方法:

但这将首先从数据库中提取所有记录

但是,我想你可以这样做:

def ar_each_slice scope, size
  (scope.count.to_f / size).ceil.times do |i|
    yield scope.scoped(:offset => i*size, :limit => size)
  end
end
并将其用作:

ar_each_slice(User.scoped, 1000) do |slice|
  some_method slice.all
end
它将首先获取记录数(使用COUNT),然后使用LIMIT子句获取1000 x 1000,并将其传递给您的块。

我忘了使用,但Chandra建议使用它。这是正确的方法


使用
.all
将要求数据库检索所有记录,将它们传递给Ruby保存,然后在内部对它们进行迭代。如果您的数据库正在增长,那么这是一种非常糟糕的处理方法。这是因为记录的glob将使DBM在增长的过程中更加努力地工作,而Ruby将不得不分配越来越多的空间来保存它们。因此,您的响应时间将增加

更好的解决方案是使用
:limit
:offset
选项告诉DBM依次在偏移量0处找到前1000条记录,然后在偏移量1处找到下1000条记录,以此类推。保持循环,直到没有更多记录为止

在开始询问之前,你可以通过做一个
.count
来确定你需要循环多少次,除非你的where子句很糟糕,否则这是非常快的,或者只是循环直到没有记录回来。

我忘了使用,但钱德拉建议了。这是正确的方法


使用
.all
将要求数据库检索所有记录,将它们传递给Ruby保存,然后在内部对它们进行迭代。如果您的数据库正在增长,那么这是一种非常糟糕的处理方法。这是因为记录的glob将使DBM在增长的过程中更加努力地工作,而Ruby将不得不分配越来越多的空间来保存它们。因此,您的响应时间将增加

更好的解决方案是使用
:limit
:offset
选项告诉DBM依次在偏移量0处找到前1000条记录,然后在偏移量1处找到下1000条记录,以此类推。保持循环,直到没有更多记录为止


在开始询问之前,您可以通过执行
.count
来确定需要循环多少次,这非常快,除非您的where子句很糟糕,或者只是循环直到没有记录返回。

因为Rails 2.3可以指定
批量大小

User.find_in_batches(:batch_size =>1000) do |users|
    some_method(users)
end

在这种情况下,框架将对每1000条记录运行一次select查询。如果您正在处理大量记录,它会保持内存较低

由于Rails 2.3,可以指定
批量大小

User.find_in_batches(:batch_size =>1000) do |users|
    some_method(users)
end

在这种情况下,框架将对每1000条记录运行一次select查询。如果您正在处理大量记录,它会保持内存较低

Ruby还是Rails?如果这是来自数据库,您可能不想立即将
all()
拉入内存。如何处理您的接受率?考虑到你的声誉,53%是低的。Ruby,还是Rails?如果这是来自数据库,您可能不想立即将
all()
拉入内存。如何处理您的接受率?考虑到您的声誉,53%是较低的。那么循环originall users集合,然后将1K传递给方法调用的外部循环呢?`users[0..999]仍然需要读取整个集合,然后删除前1000个。如果表中包含2000000行,这将是一种资源占用。那么循环originall users集合,然后将1K传递给方法调用的外部循环呢?`users[0..999]仍然需要读取整个集合,然后删除前1000行。如果表中包含2000000行,这将是一种资源占用。