首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用ActiveRecord对每种方法进行查询优化

用ActiveRecord对每种方法进行查询优化
EN

Stack Overflow用户
提问于 2016-05-17 09:20:15
回答 1查看 859关注 0票数 0

下面提到的查询花费了太多的时间,无法理解如何优化它。

守则和协会:

代码语言:javascript
复制
temp = []
platforms = current_user.company.advisory_platforms
platforms.each{ |x| temp << x.advisories.published.collect(&:id) }

class Advisory
  has_many :advisory_platforms,:through =>:advisory_advisory_platforms
end

class AdvisoryPlatform
  has_many :companies,:through => :company_advisory_platforms
  has_many :company_advisory_platforms,:dependent => :destroy
  has_many :advisory_advisory_platforms,:dependent => :destroy
  has_many :advisories, :through => :advisory_advisory_platforms
end
EN

回答 1

Stack Overflow用户

发布于 2016-05-18 19:50:47

在您的示例中有三个明显的性能问题。

首先,使用each迭代记录,这意味着要将整个记录集一次性加载到内存中。如果您必须以这种方式迭代记录,则应该始终使用find_each,因此它是done in batches

其次,each循环的每一次迭代都要执行一个额外的SQL调用,以获得其结果。您希望将SQL调用限制在最低限度。

第三,实例化整个Rails模型只是为了收集单个值,这是非常浪费的。实例化Rails模型是昂贵的

我要用两种方法解决这些问题。首先,构建一个ActiveRecord关系,它将访问在一个查询中所需的所有数据。其次,使用pluck获取所需的id,而无需支付模型实例化成本。

您没有指定published在做什么,所以我假设它是Advisory上的一个作用域。您还省略了一些数据模型,所以我必须对连接模型进行假设。

代码语言:javascript
复制
advisory_ids = AdvisoryAdvisoryPlatform
  .where(advisory_platform_id: current_user.company.advisory_platforms)
  .where(advisory_id: Advisory.published)
  .pluck(:advisory_id)

如果将Relation对象作为字段的值传递,ActiveRecord将将其转换为子查询。

所以

代码语言:javascript
复制
where(advisory_id: Advisory.published)

类似于

代码语言:javascript
复制
WHERE advisory_id IN (SELECT id FROM advisories WHERE published = true)

(或者不管published在做什么)。

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

https://stackoverflow.com/questions/37272038

复制
相关文章

相似问题

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