简体   繁体   English

Rails数据库查询ROR

[英]Rails Database Query ROR

First of all, I am still new to ROR and I am trying to come up with more efficient way to do a database query for my datatables. 首先,我对ROR还是陌生的,我正在尝试提出一种更有效的方法来对我的数据表进行数据库查询。

My Model association 我的模特协会

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

In my DataTables 在我的数据表中

          <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 and get_ltv method as follows find_customer_id和get_ltv方法如下

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

The problem with the code is that, currently I have over 1000 active record objects that I loop through, when find_customer_id method is hit it will find customer with the given email address and the query takes over 15 sec to process. 代码存在的问题是,当前我遍历了1000个活动记录对象,当单击find_customer_id方法时,它将找到具有给定电子邮件地址的客户,并且查询要花15秒钟以上的时间来处理。

In my situation, what would be the best way to approach this? 以我的情况,解决此问题的最佳方法是什么?

solution that I have though about: 1. join the tables to so that I don't have to call another table 2. lazy load, only load the objects when needed 我有以下解决方案:1.将表连接到,这样我就不必调用另一个表了。2.延迟加载,仅在需要时加载对象

Some suggestion will be greatly appreciated 一些建议将不胜感激

thank you 谢谢

Your query by email ID should not take so much time. 您通过电子邮件ID查询不会花费太多时间。

  1. Add index for the email column in Customers table (Refer this for adding indexes through Active record migrations - http://apidock.com/rails/v4.2.1/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index ) 添加索引客户表中的电子邮件列(请参阅本作将通过活动记录迁移指标- http://apidock.com/rails/v4.2.1/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index

  2. Your code shows calling the find_customer_id twice. 您的代码显示两次调用find_customer_id Do that once so only 1 database query is fired 这样做一次,仅触发1个数据库查询

  3. You need not write a wrapper method - Customer.find_by_email(customer_email) also works 您无需编写包装方法Customer.find_by_email(customer_email)也可以使用

To optimize further, you can collect all the customer IDs you need to check for existence in database in one loop, and fire a single database query: Customer.where(email: [list of customer emails]) 为了进一步优化,您可以在一个循环中收集检查数据库中是否存在所需的所有客户ID,并触发一个数据库查询: Customer.where(email: [list of customer emails])

The main problem is that you're missing an association between customer and survey. 主要问题是您缺少客户和调查之间的关联。 You could make one by joining on the email 您可以通过加入电子邮件来创建一个

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

but this is a somewhat sketchy approach. 但这是一种粗略的方法。 Does you application know the ID of the customer when they fill a survey? 您的应用程序在填写调查表时是否知道客户的ID? Or can these surveys be filled by anyone and you make the link if someone claims to have the same email as a customer? 还是可以由任何人填写这些调查,如果有人声称与客户拥有相同的电子邮件,则您可以链接吗?

In any case you need both the email columns to be indexed and if you make an association between the two you will be able to write the following in your controller code. 无论如何,您都需要对两个电子邮件列都进行索引,并且如果在两者之间建立了关联,则可以在控制器代码中编写以下内容。

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

This will make a database query which eager loads all the surveys and customers that you're about to display so that inside the loop you can use survey.customer without calling a new query for each row. 这将使数据库查询,它渴望加载您将要显示的所有调查和客户,以便在循环内可以使用survey.customer而不为每一行调用新查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM