使用Rails 5.0和Postgresql的开发环境。我们有3个通过关系实现has_many的机型:
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的活动列表的帐户:
class DashboardController < ApplicationController
def index
render json: Account.list_campaigns
end
end结果看起来不错,但有额外的查询来获得我们意想不到的活动:
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)为什么要执行这些额外的查询?在这种情况下,如何关闭预加载以优化性能,因为会有大量的数据?
发布于 2017-03-24 14:00:23
我们发现急切加载是由控制器中的render json触发的。并且select语句中标记的列campaign_ids被用来急切加载。为了解决这个问题,我们替换查询:
self.joins(:account_campaigns).select('accounts.id, array_agg(campaign_id) AS campaign_ids').group('accounts.id')出自:
self.joins(:account_campaigns).select('accounts.id, array_agg(campaign_id) AS cids').group('accounts.id')唯一的区别是将标签campaign_ids更改为cids (或与campaign_ids不同的任何内容),以避免运行时的急切负载。
https://stackoverflow.com/questions/42943320
复制相似问题