mysql - 防止 Rails 缓存 ActiveRecord 查询的结果

标签 mysql ruby-on-rails ruby caching activerecord

我有一个 rake 任务需要遍历大量记录(称为商家),每个记录都有大量关联项目。我的问题是,由于 Rails 会自动缓存我的数据库查询结果,我很快就将我的工作人员放入交换空间。

简而言之,我想知道如何运行如下命令:

Merchant.all.each { |m| items = m.items }

每次都不会缓存“items”的值。

我试过:

Merchant.all.each do |m|
  ActiveRecord::Base.connection.uncached do
   items = m.items
 end
end

我还尝试将其添加到我的商家模型中:

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

尝试进行一些错误检查,然后记录结果。

最佳答案

查询缓存不是这里的主要问题。 Rails 无论如何都会“缓存”您的对象。

查询缓存只是一种“哈希查找”,可防止 Rails 不必要地访问数据库,它不控制 ruby​​(或 Rails)如何存储关联内部返回的对象。

例如试试这个(即使未缓存):

m = Merhant.first # <- m is loaded from DB
m.items           # <- items are loaded from DB and STORED(!) in m
m.items           # <- items are returned from the association stored in m
m.items.reload    # <- hits the DB (or the query cache)
m.instance_variable_get("@items") # <- returns the actual stored items

现在,当您在 each 循环中执行 m.items 时,您只需将所有的 Merhcant 实例与它们的所有项目一起填充,并且垃圾收集器无法释放任何东西,因为当您在循环中时,所有对象都从 all 数组中引用。

所以解决方案是像 Victor 提议的那样做,这样可以防止触发“关联存储”。

关于mysql - 防止 Rails 缓存 ActiveRecord 查询的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6934415/

相关文章:

ruby-on-rails - has_and_belongs_to_many 关系的自定义 Active Admin 表单输入

ruby-on-rails - 无法在 Prawn 中绘制边界框边框

php - 我可以用 mysql(不是 mysqldump)转储数据库吗?

jquery - rails 的当前图像 slider

ruby-on-rails - have_selector 在 RSpec 测试中失败,但页面呈现正确并且标签存在

ruby-on-rails - 在初始化程序中获取 rake 任务名称

ruby-on-rails - 在 ruby​​ on rails 中包含 httparty 的问题

php - 我的代码中有什么问题,行计数方法没有返回受影响的行?

c# - 方法 'Open' 没有重载需要 1 个或多个参数

mysql - 如何在shell脚本中将MySQL查询输出转换为数组?