sql - 当一个包罗万象的 SELECT 已经运行时,为什么要运行单个 SELECT 查询? (Rails/ActiveRecord)

标签 sql ruby-on-rails activerecord ruby-on-rails-3.2 query-optimization

我有以下代码(注意 includes.each ):

subscribers = []
mailgroup.mailgroup_members.opted_to_receive_email.includes(:roster_contact, :roster_info).each { |m|
  subscribers << { :EmailAddress => m.roster_contact.member_email,
                   :Name => m.roster_contact.member_name,
                   :CustomFields => [ { :Key => 'gender', 
                                        :Value => m.roster_info.gender.present? ? m.roster_info.gender : 'X' 
                                    } ] 
                  } if m.roster_contact.member_email.present?
}
subscribers

相应地,我在日志中看到以下内容(即 select * from ROSTER_INFO ... IN (...) ):
SELECT `ROSTER_INFO`.* FROM `ROSTER_INFO` WHERE `ROSTER_INFO`.`ID` IN ('1450', '1000', '1111')

然而紧随其后的是select * from ROSTER_INFO对于已在 IN 中指定的每个 ID上一个查询的列表:
RosterInfo Load (84.8ms)  SELECT `ROSTER_INFO`.* FROM `ROSTER_INFO` WHERE `ROSTER_INFO`.`ID` = '1450' LIMIT 1
RosterInfo Load (59.2ms)  SELECT `ROSTER_INFO`.* FROM `ROSTER_INFO` WHERE `ROSTER_INFO`.`ID` = '1000' LIMIT 1
RosterInfo Load (56.8ms)  SELECT `ROSTER_INFO`.* FROM `ROSTER_INFO` WHERE `ROSTER_INFO`.`ID` = '1111' LIMIT 1

select *已经在 ROSTER_INFO 上完成了在所有感兴趣的 ID ( IN (...) ) 上,为什么另一个 select *为每个相同的 ID 再次完成?没有 ActiveRecord已经知道了ROSTER_INFO每个 ID 的列?

(同时,没有对 ROSTER_CONTACT 的单独查询,但是如果我从 :roster_contact 方法中删除 includes,那么 ROSTER_INFO 不会再次被查询,但 ROSTER_CONTACT 是。)

名册信息模型(节略)
class RosterInfo < ActiveRecord::Base
  self.primary_key = 'ID'
end

名册联系人模型(节略)
class RosterContact < ActiveRecord::Base
  self.primary_key = 'ID'

  has_many :mailgroup_members, foreign_key: 'rosterID'
  has_many :mailgroups, through: :mailgroup_members

  has_one :roster_info, foreign_key: 'ID'     # can use this line
  #belongs_to :roster_info, foreign_key: 'ID' # or this with no difference

  def member_name                             # I added this method to this
    roster_info.member_name                   # question only *after* having
  end                                         # figured out the problem.
end

RosterWeb 模型(节略)
class RosterWeb < ActiveRecord::Base
  self.primary_key = 'ID'
end

邮件组模型(节略)
class Mailgroup < ActiveRecord::Base
  self.primary_key = 'ID'

  has_many :mailgroup_members, foreign_key: 'mailCatID'

  has_one :mailing_list, foreign_key: :legacy_id
end

邮件组成员模型(节略)
class MailgroupMember < ActiveRecord::Base
  self.primary_key = 'ID'

  belongs_to :mailgroup, foreign_key: 'mailCatID'
  belongs_to :roster_contact, foreign_key: 'rosterID'
  belongs_to :roster_info, foreign_key: 'rosterID'
  belongs_to :roster_web, foreign_key: 'rosterID'

  scope :opted_to_receive_email, joins(:roster_web).where('ROSTER_WEB.receiveEmail=?', 1)
end

最佳答案

原来这个问题与m.roster_contact.member_name有关-- 不幸的是我做了 member_name roster_contact的方法本身(间接)查询 roster_info.member_name .我通过改变线路解决了这个问题

:Name => m.roster_contact.member_name,

直接查询roster_info如下
:Name => m.roster_info.member_name,

我很抱歉给您带来麻烦!

关于sql - 当一个包罗万象的 SELECT 已经运行时,为什么要运行单个 SELECT 查询? (Rails/ActiveRecord),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13039110/

相关文章:

sql - Rails 查询同一字段上的多个条件

MYSQL:两个表之间的 UNION 结果,如果在第二个表中找到 PK,则省略第一个表中的记录

sql - 如何在 SQL Server 中随时间插入纬度/经度?

sql - 使用 SQL 语句获取数据库中的字段数?

ruby-on-rails - 登录 ActiveAdmin 时出现路由错误

ruby-on-rails - rails : find all parents with all children having a particular attribute

mysql - SQL错误代码: 1364 Field 'CustomerNumber' doesn't have a default value

ruby-on-rails - rails : Regex to exclude input after a character in ruby?

ruby-on-rails - 无法在 Rails 中将电子邮件作为 URL 中的参数发送

ruby-on-rails - 无法在 Rails 3.2.3 中批量分配 protected 属性