如何改进此查询?
f, s, t, ft, et, tf = [], [], [], [], [], []
reports = pros.each do |pro|
pro_report = pro.project_reports.where(project_id: project_id).size
f << pro_report.where(position: 1).size
s << pro_report.where(position: 2).size
t << pro_report.where(position: 3).size
ft << pro_report.where('position BETWEEN ? AND ?', 4, 10).size
et << pro_report.where('position BETWEEN ? AND ?', 11, 20).size
tf << pro_report.where('position BETWEEN ? AND ?', 21, 50).size
end
{f: f.sum, s: s.sum, t: t.sum, ft: ft.sum, et: et.sum, tf: tf.sum}
创建Postgres VIEW是个好主意吗?我怎样才能做到这一点? 欢迎任何速度或结构的改进。
谢谢。
答案 0 :(得分:1)
由于在您的方案中,大多数查询都在position
字段上,因此我建议在该字段上进行制作和索引。
答案 1 :(得分:1)
不需要循环。如下所示
pro_ids = pros.map(&:id)
pro_reports = ProjectReport.where(project_id: pro_ids)
f = pro_reports.where(position: 1).size
s = pro_reports.where(position: 2).size
t = pro_reports.where(position: 3).size
ft = pro_reports.where('position BETWEEN ? AND ?', 4, 10).size
et = pro_reports.where('position BETWEEN ? AND ?', 11, 20).size
tf = pro_reports.where('position BETWEEN ? AND ?', 21, 50).size
请记住在位置列中有适当的索引 - 在这种情况下是必须的。
或者,您可以按位置对数据库分组执行单个查询,然后使用Ruby Hash#select
和Rails Enumerable#sum
来获取所需的值:
pro_ids = pros.map(&:id)
hash_pos_count = ProjectReport.where(project_id: pro_ids).group(:position).size
f = hash_pos_count.select{ |k, v| k == 1 }.first.last
...
ft = hash_pos_count.select{ |k, v| k >= 3 && k <= 10 }.sum(&:last)
...