【问题标题】:How can I make these Active Record queries faster?如何使这些 Active Record 查询更快?
【发布时间】:2021-09-05 16:09:13
【问题描述】:

我正在使用 Active Record 向 postgres 数据库发送一些查询。

我有一个用户模型、一个业务模型和一个名为 UserBiz 的加入者。

我提到的查询会遍历整个 UserBiz 集合,然后过滤掉与用户提供的类别和搜索匹配的企业。

 if !params[:category].blank?
    dataset = UserBiz.all.includes(:business, :user).select{|ub| (ub.business.category.downcase == params[:category].downcase) }
 else 
    dataset = UserBiz.all.includes(:business, :user)
 end

 if !params[:search].blank?
    dataset = dataset.select{|ub| (ub.business.summary.downcase.include? params[:search].downcase) || (ub.business.name.downcase.include? params[:search].downcase) }
 end

这些“工作”,但问题是当我将 25 万个 UserBiz 放入我的数据库以查看发生了什么时,一次搜索或类别更改需要 15 秒。如何使这些查询更快?

【问题讨论】:

    标签: sql ruby-on-rails postgresql rails-activerecord eager-loading


    【解决方案1】:

    select 在您的代码中将所有内容加载到内存中,这在处理大量记录时对性能非常不利。

    你必须在数据库中进行过滤,像这样。

    UserBiz
      .includes(:business, :user)
      .where("LOWER(businesses.category) = LOWER(?)", params[:category])
    

    【讨论】:

      【解决方案2】:

      这很慢,因为您从 UserBiz 中选择了所有数据。 尝试分页。 pagey、will_paginate 等。

      【讨论】:

      • 我已经在我的应用程序中实现了我自己的分页版本。我需要帮助的是查询数据库中的所有业务并选择具有用户正在寻找的类别或搜索词的业务。显示它们并不是真正的问题。我将 React Native 用于前端,并且我有一个 Flatlist 可以一次呈现 7 个业务。由于这些选择方法,在我搜索或更改类别之前,一切都运行顺利。我意识到他们必须遍历每个 UserBiz,但用户如何才能搜索整个应用程序?
      • 最好的方法是返回与类别或搜索匹配的前 x 个结果。我已经尝试过 .first(x) 和 .take(x) 等,但这些方法似乎仍然会在返回结果之前遍历整个集合。 .limit 只能在 select 之前调用,这违背了搜索整个集合的目的。
      • 为什么不对搜索结果进行分页?我提到您正在选择所有数据,这就是您的查询速度慢的原因。
      • 我不熟悉那些库。就目前的情况进行基本过滤查询似乎有点过头了,因为在结果从数据库返回后我有自己的分页,所以我需要重构它等等我会把你的建议保存为最后的手段
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-02
      • 1970-01-01
      • 2012-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多