记忆化是否适用于活动记录关系?

Does memoization works with active record relations?

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

def all_users 
  @users ||= User.all
end

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

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

使用 #all 时要小心,因为它会将所有记录加载到内存中。这可能很慢并且会消耗大量内存。在较长的 运行.

中,进行单独的 User.find(X) 查询对您来说会更好

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

所以如果你做

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

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

但是,如果您使用 wherejoins 等方法,... return 一个新关系,那么如果需要这些关系的数据,则需要访问数据库.

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) 如果你想允许缺失值)。