Rails缓存数据库查询和最佳实践 [英] Rails Caching DB Queries and Best Practices

查看:101
本文介绍了Rails缓存数据库查询和最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我网站上的数据库负载越来越高,因此现在是时候缓存常见查询了,这些查询每小时被调用1000次,而结果没有变化. 因此,例如,在我的城市模型上,我执行以下操作:

The DB load on my site is getting really high so it is time for me to cache common queries that are being called 1000s of times an hour where the results are not changing. So for instance on my city model I do the following:

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

因此,现在当我第一次访问DB时可以使用City.find(1)时,但是接下来的1000次我从内存中获得了结果.伟大的.但是大多数对city的调用不是City.find(1),而是@ user.city.name,其中Rails不使用fetch而是再次查询DB ...这是有道理的,但并不完全是我想要的.

So now when I can City.find(1) the first time I hit the DB but the next 1000 times I get the result from memory. Great. But most of the calls to city are not City.find(1) but @user.city.name where Rails does not use the fetch but queries the DB again... which makes sense but not exactly what I want it to do.

我可以做City.find(@ user.city_id),但这很丑.

I can do City.find(@user.city_id) but that is ugly.

所以我对你们的问题.聪明人在做什么?什么是 正确的方法来做到这一点?

So my question to you guys. What are the smart people doing? What is the right way to do this?

推荐答案

关于缓存,有几点要点:

With respect to the caching, a couple of minor points:

使用斜杠分隔对象类型和id是值得的,这是rails的约定.更好的是,ActiveRecord模型提供了cacke_key实例方法,该方法将提供表名和ID,"cities/13"等的唯一标识符.

It's worth using slash for separation of object type and id, which is rails convention. Even better, ActiveRecord models provide the cacke_key instance method which will provide a unique identifier of table name and id, "cities/13" etc.

对after_save过滤器进行一次小的更正.由于手头有数据,因此最好将其写回到缓存中,而不要删除它.这样可以节省您一次访问数据库的时间;)

One minor correction to your after_save filter. Since you have the data on hand, you might as well write it back to the cache as opposed to delete it. That's saving you a single trip to the database ;)


def after_save
  Rails.cache.write(cache_key,self)
end

关于问题的根源,如果您不断拉@ user.city.name,则有两个实际选择:

As to the root of the question, if you're continuously pulling @user.city.name, there are two real choices:

  • 将用户的城市名称反规范化为用户行. @ user.city_name(保留city_id外键).该值应在保存时写入.

-或-

  • 实施您的User.fetch方法以渴望加载城市.仅在城市行的内容永不更改(即名称等)的情况下才执行此操作,否则就缓存无效而言,您可能会打开蠕虫病毒罐.

个人意见: 实现基于基本ID的提取方法(或使用插件)以与memcached集成,并将城市名称反规范化为用户所在的行.

Personal opinion: Implement basic id based fetch methods (or use a plugin) to integrate with memcached, and denormalize the city name to the user's row.

我个人并不是缓存模型样式插件的忠实拥护者,我从未见过这样一个节省大量开发时间的应用程序,而我却并不着急.

I'm personally not a huge fan of cached model style plugins, I've never seen one that's saved a significant amount of development time that I haven't grown out of in a hurry.

如果您要查询的数据库查询过多,那么绝对值得一试(如果没有的话)(通过:include)来进行急切的加载.那应该是减少数据库查询数量的第一步.

If you're getting way too many database queries it's definitely worth checking out eager loading (through :include) if you haven't already. That should be the first step for reducing the quantity of database queries.

这篇关于Rails缓存数据库查询和最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆