我有两个模型:用户和分数>用户有很多分数
用户模型包含有关用户的一般信息 - 名称,位置等。 模型分数包含日期,分数和quality_score值。
我需要的是一种有效的方法来获取20个唯一用户的列表,这些用户在给定的日期范围内具有最佳分数。如果用户1具有前3个分数,我只希望他们的最高分与他们的名字相对应,而对于用户2来说他们的最佳分数是他们的名字。 (我的测试数据有000个用户和000000个分数)。
我设法使用此功能(在其他SO用户的帮助下):
@top_users = User.limit(20).
select("`users`.*").
joins(:scores).
where("datetime_utc >= ? AND datetime_utc <= ?", @utc_time_slot , @utc_time_slot_end).
group('user_id').
order("max(quality_score) DESC, max(score) DESC")
(感谢Mario Visic和Chris Bailey)但是查询花了不可思议的长时间运行 - 我不禁想到有更有效的方法来完成这项工作......
任何指针/想法?谢谢!
答案 0 :(得分:0)
最快的解决方案是将用户的最佳分数反规范化到users
表中并对其进行索引,但如果非规范化对您来说不是一个实用的选项,我建议在scores.quality_score
上创建一个索引, /或scores.datetime_utc
,具体取决于哪个会更好地减少查询范围。然后我打破2中的查询,如下所示:
top_user_scores = Score.limit(20).
where("datetime_utc >= ? AND datetime_utc <= ?", @utc_time_slot , @utc_time_slot_end).
group('user_id').
order("max(quality_score) DESC, max(score) DESC")
User.find(top_user_scores.map(&:user_id))