在我的 Rails 应用程序的某个时刻,我从缓存中检索了大量 ActiveRecord 对象。但是,这些记录中的一些可能已从数据库本身中删除,因为它们存储在缓存中,因此我循环记录并检查每个记录以查看它是否存在。这需要相当多的时间。有没有更有效的方法来做到这一点?
4 回答
从数据库中删除记录时,是否有理由不从缓存中删除记录?
如果您要将这些记录存储在缓存中并需要它们与数据库同步,那么当您从数据库中删除它们时,请确保也从缓存中删除它们的存在,从而为您节省昂贵的查询稍后检查冗余数据。
这也可以被认为是一个数据库设计问题,而不是一个真正的 rails 问题。从这个角度来看,你能在你的表中添加一个具有唯一索引的 AUTO INCREMENT 字段吗?
即使在进行记录存在检查时,活动记录查询接口最终也必须依赖数据库进行查找。因此,无论界面有多好,如果数据库必须做很多工作,它都需要时间,而且不是 rails “故障”。让数据库尽可能快地验证您想要的记录。
如果您熟悉 oracle,这与将 oracle rowid 存储在查询中以便以后能够验证现有记录的想法相同。
正如 Danny 所指出的那样,也许缓存大量记录并在以后使用它们对您的应用程序来说是个坏主意。你能阅读,然后立即处理你的记录吗?
这些建议都不是快速解决方案。
如果您要检查的记录数量确实很大,那么您可以通过进行批量传输来分摊运送它们的成本:创建一个临时表,在其中插入大量行从缓存中取出,然后将临时表与原始表连接起来。然后,您的 DBMS 将为您执行循环。
如果缓存的结果包括您感兴趣的记录的主键,您可以通过从数据库中仅选择这些键并查看返回的内容来轻松过滤结果。然后只需踢出过时的记录,你就可以开始了。
results_from_cache = $redis.get("users")
cached_user_ids = results_from_cache.map(&:id)
actual_user_ids = User.where(id: user_ids).pluck(:id)
results_minus_stale = results_from_cache.select do |user|
actual_user_ids.include?(user.id)
end