首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails:意外的急切加载具有许多连接模型

Rails:意外的急切加载具有许多连接模型
EN

Stack Overflow用户
提问于 2017-03-22 13:18:39
回答 1查看 47关注 0票数 0

使用Rails 5.0和Postgresql的开发环境。我们有3个通过关系实现has_many的机型:

代码语言:javascript
复制
class Account < ApplicationRecord
  has_many :account_campaigns
  has_many :campaigns, through: :account_campaigns

  def self.list_campaigns
    self.joins(:account_campaigns).select('accounts.id, array_agg(campaign_id) AS campaign_ids').group('accounts.id')
  end
end

class Campaign < ApplicationRecord
  has_many :account_campaigns
  has_many :accounts, through: :account_campaigns
end

class AccountCampaign < ApplicationRecord
  belongs_to :account
  belongs_to :campaign
end

以及一个控制器,该控制器具有一个动作,用于获取以json格式作为api的活动列表的帐户:

代码语言:javascript
复制
class DashboardController < ApplicationController
  def index
    render json: Account.list_campaigns
  end
end

结果看起来不错,但有额外的查询来获得我们意想不到的活动:

代码语言:javascript
复制
Started GET "/" for 127.0.0.1 at 2017-03-22 12:06:04 +0700
Processing by DashboardController#index as HTML
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Account Load (0.5ms)  SELECT accounts.id, array_agg(campaign_id) AS campaign_ids FROM "accounts" INNER JOIN "account_campaigns" ON "account_campaigns"."account_id" = "accounts"."id" GROUP BY accounts.id

"### extra queries here ###"
   (0.5ms)  SELECT "campaigns".id FROM "campaigns" INNER JOIN "account_campaigns" ON "campaigns"."id" = "account_campaigns"."campaign_id" WHERE "account_campaigns"."account_id" = $1  [["account_id", 1]]
   (0.4ms)  SELECT "campaigns".id FROM "campaigns" INNER JOIN "account_campaigns" ON "campaigns"."id" = "account_campaigns"."campaign_id" WHERE "account_campaigns"."account_id" = $1  [["account_id", 2]]
Completed 200 OK in 100ms (Views: 57.3ms | ActiveRecord: 18.8ms)

为什么要执行这些额外的查询?在这种情况下,如何关闭预加载以优化性能,因为会有大量的数据?

EN

回答 1

Stack Overflow用户

发布于 2017-03-24 14:00:23

我们发现急切加载是由控制器中的render json触发的。并且select语句中标记的列campaign_ids被用来急切加载。为了解决这个问题,我们替换查询:

代码语言:javascript
复制
self.joins(:account_campaigns).select('accounts.id, array_agg(campaign_id) AS campaign_ids').group('accounts.id')

出自:

代码语言:javascript
复制
self.joins(:account_campaigns).select('accounts.id, array_agg(campaign_id) AS cids').group('accounts.id')

唯一的区别是将标签campaign_ids更改为cids (或与campaign_ids不同的任何内容),以避免运行时的急切负载。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42943320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档