【发布时间】:2011-10-19 13:12:04
【问题描述】:
我有一个 rake 任务,需要遍历大量记录(称为 Merchants),每条记录都有大量关联项目。我的问题是,由于 Rails 自动缓存了我的数据库查询的结果,我很快就将我的工作人员放入了交换空间。
简而言之,我想知道如何运行如下命令:
Merchant.all.each { |m| items = m.items }
每次都不会缓存“items”的值。
我试过了:
Merchant.all.each do |m|
ActiveRecord::Base.connection.uncached do
items = m.items
end
end
我也尝试将其添加到我的 Merchant 模型中:
def items_uncached
self.class.uncached { items }
end
然后改为调用 items_uncached,但最终我访问的每组新项目仍然会占用内存。
我正在运行 Rails 2.3.10、Ruby 1.9.2 并使用 Mysql 进行存储。
提前感谢您的想法!
***编辑:
这是我正在处理的实际代码:
File.open(output, "w") do |f|
Merchant.all.each do |m|
items = m.items
invalid_image_count = 0
items.each do |i|
invalid_image_count += 1 unless i.image_valid?
end
invalid_categories = items.select { |i| !i.categories_valid? }.count
f.puts "#{m.name} (#{m.id}): #{invalid_image_count} invalid images, " +
"#{invalid_categories} invalid categories"
end
end
尝试进行一些错误检查,然后记录结果。
【问题讨论】:
-
你想做什么在这里不是很清楚;也许您正在寻找类似
ActiveRecord::Base#find_each的东西? -
好的,是的,我刚刚查看了 find_each,这实际上可能会有所帮助。我试试看。
-
为了更好地表达,当我在控制台中运行这段代码时:Merchant.all.each { |m|项目 = m.项目; print "#{m.id} " },每次迭代时我的内存使用量都会增加。我的猜测是,这是因为 m.items 产生了 1 到 10,000 多个 ActiveRecords。
-
这是意料之中的:Ruby 的垃圾收集器很少被触发,因此它在退出块时不太可能释放内存。相反,它会在获得下一个结果时重新使用它。如果下一组结果更大,将分配更多内存。这不考虑 AR(或 Rails,或 gem/插件,或您的代码等)中的潜在内存泄漏。我对 2.3(从 3 开始)了解不多,但我认为它不会在不显式打开它的情况下查询缓存(即使用 memcache)。
-
什么是物品?该代码实际上是做什么的?它是在它自己的块中还是其他什么东西,而你刚刚取出了这个块?
标签: mysql ruby-on-rails ruby caching activerecord