我在记录之间有以下关系:
鉴于 Project 记录,我需要一个与项目相关的所有资源相关的所有国家/地区的列表。任何国家都不应该出现过多次。
要做到这一点,忽略明显的性能问题,我可以为资源添加一个方法:
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)
国家/地区负载(0.4ms)SELECT“countries”。* FROM“countries”WHERE “国家”。“id”IN(19,31,64,82,197,169,1,161,167)
[更新]
通过使用joins
而不是includes
,我的最新尝试速度大约是上述解决方案的两倍,每个资源的点击次数总计约为0.2秒:
Country.joins(resource_locations: {resource: :project}).where(resources: {project_id: self}).uniq
答案 0 :(得分:1)
这应该没问题:
resources.includes(:countries).map(&:countries).flatten.uniq
includes
方法通过预先加载适当的关联来解决N + 1查询的问题。