我网站上的数据库负载变得非常高,所以现在是我缓存常见查询的时候了,这些查询每小时被调用 1000 次,而结果没有改变。
因此,例如在我的城市模型上,我执行以下操作:
def self.fetch(id)
Rails.cache.fetch("city_#{id}") { City.find(id) }
end
def after_save
Rails.cache.delete("city_#{self.id}")
end
def after_destroy
Rails.cache.delete("city_#{self.id}")
end
所以现在当我第一次点击数据库时我可以 City.find(1) 但接下来的 1000 次我从内存中得到结果。伟大的。但是大多数对 city 的调用不是 City.find(1) 而是 @user.city.name ,其中 Rails 不使用 fetch 而是再次查询数据库......这是有道理的,但不完全是我想要它做的。
我可以做 City.find(@user.city_id) 但这很难看。
所以我想问你们。聪明的人在做什么?什么是
这样做的正确方法是什么?
最佳答案
关于缓存,有几个小点:
值得使用斜杠来分隔对象类型和 id,这是 Rails 约定。更好的是,ActiveRecord 模型提供了 cacke_key 实例方法,该方法将提供表名和 id、“cities/13”等的唯一标识符。
对 after_save 过滤器的一个小修正。由于您手头有数据,您不妨将其写回缓存,而不是将其删除。这为您节省了一次访问数据库的时间;)
def after_save
Rails.cache.write(cache_key,self)
结尾
至于问题的根源,如果你不断拉@user.city.name,有两个真正的选择:
-或者-
个人意见:
实现基本的基于 id 的 fetch 方法(或使用插件)与 memcached 集成,并将城市名称非规范化为用户行。
我个人不是缓存模型样式插件的忠实拥护者,我从未见过可以节省大量开发时间的插件,而且我还没有匆忙完成。
如果您收到太多的数据库查询,那么绝对值得检查一下预先加载(通过 :include)(如果您还没有)。这应该是减少数据库查询数量的第一步。
关于ruby-on-rails - Rails 缓存数据库查询和最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/344744/