【问题标题】:Does memoization works with active record relations?记忆化是否适用于活动记录关系?
【发布时间】:2018-04-30 09:10:15
【问题描述】:

假设我的模型中有一个方法如下。

def all_users 
  @users ||= User.all
end

我的模型中有其他方法,我正在为多个不同的 id 执行all_users.where(id: 123)。它会每次都执行对 db 的查询/命中,还是会直接从缓存的结果集中获取记录。

【问题讨论】:

  • 对我来说这听起来像是xy problem。您能否解释一下为什么要记住这些查询并详细说明您尝试解决的实际问题?

标签: ruby-on-rails ruby ruby-on-rails-4 memoization


【解决方案1】:

请参阅docs 关于 SQL 缓存。如果查询完全相同,将从缓存中获取结果。对不同 ID 的请求将导致单独的查询。

但是,使用#all 时要小心,因为它会将所有记录加载到内存中。这可能很慢并且会消耗大量内存。从长远来看,进行单独的User.find(X) 查询对您来说会更好。

【讨论】:

  • 所以我有一个 10 个 id 的列表,我遍历这些 id 并执行 all_users.where(id: #id) 它将执行 10 个查询?
【解决方案2】:

User.all 返回一个活动记录关系——它不会获取任何数据,直到您尝试对其进行处理(例如,在其上调用类似数组的方法)。发生这种情况时,rails 将加载关系的数据(如果尚未加载)。

所以如果你做类似的事情

all_users.sample(5)
all_users.detect {|record| ... }

那么您将只从数据库中获取一次。

但是,如果您使用诸如 wherejoins 等返回新关系的方法,那么如果需要这些关系的数据,则需要访问数据库。

all_users.where(id: 1).first
all_users.where(id: 2).first
all_users.where(id: 3).first

例如将执行 3 个查询。

如果您有一个 id 列表,最好使用User.find(ids)(或User.where(id: ids),如果您想允许缺失值)。

【讨论】:

    猜你喜欢
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多