mysql - Rails 中避免 mysql 查询的策略

标签 mysql ruby-on-rails-3

我有一个应用程序(rails 3),它基本上是一个电视节目的社交网络。这样用户就可以彼此互动以及与电视节目互动。

避免每次显示 users/tv_shows 个人资料页面时查询数据库 (mysql) 的最佳策略是什么?

例如:在电视节目简介页面中,我需要加载大量信息,例如季节、剧集、 Actor 等。为此,需要加入多个表,并且速度每天都在变慢。

我的第一个想法是将有关任何电视节目和存储的所有信息收集在一个表中,因此我不需要每次都进行这些连接。

当然我会有更好的表现,但不是最好的。我知道有很多替代方案,例如 memcache、redis 甚至 mongodb,但是解决这种情况的最佳方法是什么?

最佳答案

在我看来,最好的选择是为每个 Show 缓存一个编码对象,其中包含渲染页面所需的所有关系的预取数据。我使用 Redis 作为缓存,但您也可以使用 Memcache 或类似的东西。

shows = user.tv_shows.map do |show|
  if cached_show = $redis.get("shows:#{show.id}")
    # use the cached object
    Marshal.load(cached_show)
  else
    # cache has expired or was never created
    show.prefetch!
    # set the cache for the next visit and have it expire after +TIMEOUT+
    $redis.setnx("shows:#{show.id}", TIMEOUT, Marshal.dump(show))
    show
  end
end

在转储对象之前预取所有关系非常重要,否则在解码缓存的对象后您将访问数据库。

这是预取的示例:

class Show
  def prefetch!
    @actors ||= actors
    self
  end

  def actors
    @actors || 1.upto(10).map do |n|
      Actor.new(n)
    end
  end
end

class Actor
  def initialize(n)
    puts "initialize actor #{n}"
  end
end

show = Show.new.prefetch!
cache = Marshal.dump(show)
Marshal.load(cache).actors.length  # uses value stored in @actors

show2 = Show.new
cache2 = Marshal.dump(show2)
Marshal.load(cache2).actors.length  # calls database

关于mysql - Rails 中避免 mysql 查询的策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13072598/

相关文章:

ruby-on-rails-3 - 使用 Sidekiq 安排后台任务

ruby-on-rails-3 - mongo 的 SEO 友好 url

mysql - 无法查看 mysql 设置中的所有 hive 元存储表

c# - 如何找出对 SQL 数据库的最后更改是什么?

ruby-on-rails-3 - Mac 上的开发模式是瘦还是 unicorn ?

ruby-on-rails - Rails 无法找到 CommentsController 错误的操作 'show'

ruby-on-rails-3 - 我可以将 RefineryCMS 与 Cancan 或类似产品一起使用吗?

mysql - 对第二个表进行带条件的 SELECT

php - 获取 php 变量以选择语句不起作用

mysql - karaf + pax-jdbc 连接池已达到限制