【问题标题】:Rails Database Query RORRails 数据库查询 ROR
【发布时间】:2017-03-25 21:07:04
【问题描述】:

首先,我还是 ROR 的新手,我正在尝试提出更有效的方法来对我的数据表进行数据库查询。

我的模特协会

class Store < ActiveRecord::Base
  has_many :surveys
  has_many :customers 
end
...
class Survey < ActiveRecord::Base
  belongs_to :store
end
...
class Customer < ActiveRecord::Base
  belongs_to :store
end

在我的数据表中

          <tbody>
            <% @store.surveys.each do |survey| %>
            <tr class="th-container table-fixer">
              <td><%= find_customer_id(survey.email).nil? ? survey.first_name : link_to(survey.first_name, store_customer_path(@store, find_customer_id(survey.email))) %></td>
              <td><%= get_ltv(survey) %></td>         
            </tr>
            <% end %>
          </tbody>

find_customer_id和get_ltv方法如下

def find_customer_id(customer_email)
   BwCustomer.find_by(email: customer_email)
end

代码的问题是,目前我有超过 1000 个活动记录对象循环遍历,当 find_customer_id 方法被点击时,它会找到具有给定电子邮件地址的客户,并且查询需要 15 秒以上的时间来处理。

在我的情况下,解决这个问题的最佳方法是什么?

我的解决方案: 1. 加入表,这样我就不必调用另一个表 2. 延迟加载,只在需要的时候加载对象

一些建议将不胜感激

谢谢

【问题讨论】:

    标签: ruby-on-rails ruby database ruby-on-rails-4 rails-activerecord


    【解决方案1】:

    您通过电子邮件 ID 进行的查询应该不会花费太多时间。

    1. 为 Customers 表中的 email 列添加 index(有关通过 Active 记录迁移添加索引的信息,请参阅此处 - http://apidock.com/rails/v4.2.1/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index )

    2. 您的代码显示两次调用find_customer_id。这样做一次,只触发 1 个数据库查询

    3. 您无需编写包装方法 - Customer.find_by_email(customer_email) 也可以使用

    为了进一步优化,您可以在一个循环中收集所有需要检查数据库中是否存在的客户 ID,然后触发单个数据库查询: Customer.where(email: [list of customer emails])

    【讨论】:

      【解决方案2】:

      主要问题是您缺少客户和调查之间的关联。您可以通过电子邮件加入来制作一个

      class Survey < ActiveRecord::Base
        belongs_to :customer, primary_key: :email, foreign_key: :email
      end
      

      但这是一种有点粗略的方法。当客户填写调查问卷时,您的应用程序是否知道客户的 ID?或者,如果有人声称与客户拥有相同的电子邮件,这些调查是否可以由任何人填写,并且您可以创建链接?

      在任何情况下,您都需要对两个电子邮件列进行索引,如果您在两者之间建立关联,您将能够在控制器代码中编写以下内容。

      @store = Store.includes(surveys: :customer).find(params[store_id])
      

      这将创建一个数据库查询,该查询会预先加载您将要显示的所有调查和客户,以便在循环内您可以使用survey.customer,而无需为每一行调用新查询。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-23
        • 2016-04-25
        • 2015-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多