【问题标题】:How can I speedily check the existence of a large number of records in the database?如何快速检查数据库中是否存在大量记录?
【发布时间】:2012-11-29 02:36:38
【问题描述】:

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

【问题讨论】:

  • @Danny - 你的评论有什么帮助?我不明白为什么有人会简单地说这真的很难,并认为它在任何方面都有远程帮助。你是说算了吧,重新设计你的代码?
  • @jimmcnamara - 感谢您的反馈!你说得对,我的评论不是特别清楚。我想补充的是认识到这是在编码中更难正确处理的事情之一,希望带有一点幽默感。
  • 在从数据库中删除记录时(使用ActiveRecord回调)不能从缓存中删除相关对象吗?这样你就不必循环检查它是否存在。
  • 我想你应该重新考虑你的数据库结构,如果这不可能,那么考虑“sphinx”或更好的“thinking sphnix”,它提供比活动记录更快的缓存!

标签: mysql ruby-on-rails database activerecord


【解决方案1】:

当从数据库中删除记录时,您没有从缓存中删除记录有什么原因吗?

如果您要将这些记录存储在缓存中并需要它们与数据库同步,那么当您从数据库中删除它们时,请确保也从缓存中删除它们的存在,从而节省昂贵的查询以后必须检查冗余数据。

【讨论】:

    【解决方案2】:

    这也可以被认为是一个数据库设计问题,而不是一个真正的 Rails 问题。从这个角度来看,你能在你的表中添加一个具有唯一索引的 AUTO INCREMENT 字段吗?

    即使在进行记录存在检查时,活动记录查询接口最终也必须依赖数据库进行查找。因此,无论界面有多好,如果数据库必须做很多工作,它都需要时间,而且不是 rails “故障”。让数据库尽可能快地验证您想要的记录。

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

    正如 Danny 所指出的,也许缓存大量记录并在以后使用它们对您的应用程序来说是个坏主意。你能阅读,然后立即处理你的记录吗?

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

    【讨论】:

      【解决方案3】:

      如果您要检查的记录数量确实很大,那么您可以通过进行批量传输来分摊运送它们的成本:创建一个临时表,在其中进行大量插入您从缓存中取出的行,然后将临时表与原始表连接起来。然后,您的 DBMS 将为您执行循环。

      【讨论】:

        【解决方案4】:

        如果缓存的结果包括您感兴趣的记录的主键,您可以通过从数据库中选择这些键并查看返回的内容来轻松过滤结果。然后只需踢掉过时的记录,你就可以开始了。

        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
        

        【讨论】:

          猜你喜欢
          • 2023-03-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-07
          • 1970-01-01
          • 1970-01-01
          • 2016-12-10
          • 1970-01-01
          相关资源
          最近更新 更多