0

更新:这是我们解决它的方法。在两个代码片段生成的 sql 上运行 MYSQL Explain:

Manifest.where(assembly_id => @assembly.id).where(part_id => @part.id).exists?没有加入,跑得更快——所以它赢了!

我有以下情况:

class Assembly < ActiveRecord::Base
  has_many :manifests
  has_many :parts, :through => :manifests
end

class Manifest < ActiveRecord::Base
 belongs_to :assembly
 belongs_to :part
end

class Part < ActiveRecord::Base
 has_many :manifests
 has_many :assemblies, :through => :manifests

结尾

因此,作为极客,我和我的同事们就以下问题展开了有争议的争论:

给定一个零件和一个组件,查找它们是否在同一个清单上。

解决方案一(使用关联):

 @part.assemblies.include? @assembly

解决方案二(使用范围):

 Manifest.where(assembly_id => @assembly.id).where(part_id => @part.id).exists?

解决方案一通过内部连接来获取数据,这让讨厌跨表的阵营发疯了。但它简洁而不丑陋。

解决方案二不做内连接并使用范围(即 where 子句),但它有点难看。

解决方案一被称为低效,并且在进行分析时,它实际上运行速度稍慢。

关于这种情况的最佳实践的任何想法。

顺便说一句,为了说明问题,我从 Rails 指南中获取了代码。

4

1 回答 1

0

我会采用以下两种方式之一,而不是出于性能原因,只是为了表达清晰:

是否有属于@assembly 和@part 的清单?

Manifest.where(assembly_id: @assembly.id, part_id: @part.id).any?

或者,@assembly 和 @part 是否共享任何清单?

(@assembly.manifests & @part.manifests).any?
于 2013-06-13T08:40:14.420 回答