2012-11-29 72 views
1

在我的Rails应用程序的某个时候,我从缓存中检索了大量的ActiveRecord对象。但是,有些记录可能已从数据库本身中删除,因为它们存储在缓存中,所以我循环记录并检查每个记录是否存在。这需要相当长的时间。有没有更有效的方法来做到这一点?如何快速检查数据库中是否存在大量记录?

+5

这只是[计算机科学中最难的两件事]之一(http://martinfowler.com/bliki/TwoHardThings.html) –

+0

@Danny - 您的评论如何有用?我不明白为什么有人会简单地说这是非常困难的,并认为它以任何方式远程帮助。你是说忘记它,重新设计你的代码? –

+0

@jimmcnamara - 感谢您的反馈!你是对的,我的评论并不特别清楚。我只想补充一点,就是认识到这是编码中很难做到的事情之一,希望能带上一点幽默感。 –

回答

2

当你从数据库中删除记录时,是否没有将记录从缓存中删除?

如果您打算将这些记录存储在缓存中,并且需要它们与db同步,那么当您从db中删除它们时,请确保从缓存中删除它们的存在,因此可以节省昂贵的代价稍后必须检查冗余数据的查询。

1

这也可以被认为是一个数据库设计问题,而不是一个真正的铁轨问题。考虑到这一点,你可以添加一个AUTO INCREMENT字段,并在表中添加一个唯一的索引吗?

即使执行记录存在检查,活动记录查询接口也必须依赖数据库最终进行查找。所以,不管接口有多好,如果db需要做很多工作,它需要时间,而不是一个“故障”。让数据库尽可能快地验证你想要的记录。

如果您熟悉oracle,这与将oracle rowid存储在查询中以便能够稍后验证现有记录的想法相同。

由于Danny似乎表明,也许缓存大量记录并在以后使用它们对您的应用程序来说是个坏主意。你可以阅读,然后立即处理你的记录?

这些建议都不是一个快速解决方案。

0

如果您正在检查的记录数量真的很大,那么您可以通过批量传输一次一个地分摊运输成本:创建一个临时表,对其进行大量插入您从缓存中取出的行,然后加入临时表对原始表。你的数据库管理系统将为你做循环。

0

如果缓存中的结果包含您感兴趣的记录的主键,那么您可以通过从数据库中选择这些键并查看返回的内容,轻松过滤结果。然后,只需发布​​陈旧的记录,你就可以走了。

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 
相关问题