我在记录之间有以下关系:
给定一个项目记录,我需要一个与项目相关的所有资源相关的所有国家的列表。任何国家都不应出现超过一次。
为此忽略明显的性能问题,我可以向Resource添加一个方法:
def countries
resources.flat_map{|resource| resource.countries}.uniq
end
我的问题有两个。
有没有办法以一种高性能的方式通过查询来实现这一点?如果没有,我应该如何处理这种情况?
[更新]
@MarekLipka 的建议是:
resources.includes(:countries).map(&:countries).flatten.uniq
然而,这会导致 60 次点击,对于 20 个项目,总共需要 0.4 秒:
资源负载 (1.2ms) SELECT "resources".* FROM "resources" WHERE "resources"."project_id" = 20 ORDER BY name
ResourceLocation Load (1.0ms) SELECT "resource_locations".* FROM "resource_locations" WHERE "resource_locations"."resource_id" IN (97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126)
Country Load (0.4ms) SELECT "countries".* FROM "countries" WHERE "countries"."id" IN (19, 31, 64, 82, 197, 169, 1, 161, 167)
[更新]
joins
我最近的尝试通过使用而不是上述解决方案的速度大约是上述解决方案的两倍,includes
每个资源在大约 0.2 秒内命中 1 次:
Country.joins(resource_locations: {resource: :project}).where(resources: {project_id: self}).uniq