我有一个模型 - Link
- 有很多点击量。我想要做的是从数据库表中hits
- 列year
,month
,day
和{{}汇总每小时点击次数数据1}}。
一切正常,但是当我运行下面的代码时,我最终会在数据库上发现 1,000个查询,这看起来相当多。
hour
此处#before iteration
@hits = @link.hits.group('year, month, day, hour')
.order('year ASC, month ASC, day ASC, hour ASC')
.select('year, month, day, hour, count(*) as hits')
#inside iteration
#Line breaks are included here for easy reading
hits_per_hour =
@hits.where(
:year => t.year,
:month => t.month,
:day => t.day,
:hour => t.hour
).map(&:hits).first || 0
是一个t
对象,自首次点击收到链接后,以1小时为单位进行迭代。
我认为rails会存储查询结果而不是每次都重新查询。我也无法找到有关缓存查询结果或任何内容的任何信息。我只是完全错过了一些东西,还是这是最简单的方法?
以下是查询内容的示例(这是我在日志中以千块为单位看到的内容):
Time
答案 0 :(得分:3)
确定。所以@hits
将是一个ActiveRecord :: Relation对象 - 本质上是一个SQL查询。我相信因为每次迭代都使用不同的参数调用.where
,从而改变了查询,Rails决定必须重新运行每小时的查询。
最简单的修复可能是在迭代之前将Relation'折叠'到数组中,然后使用纯Ruby来选择每次所需的结果:
@hits = @link.hits.group('year, month, day, hour')
.order('year ASC, month ASC, day ASC, hour ASC')
.select('year, month, day, hour, count(*) as hits').all
然后:
hits_per_hour = (@hits.select{|record| record.year == t.year && record.month == t.month && record.day == t.day && record.hour == t.hour}.map(&:hits).first || 0)
但是,我不认为这实际上可能是最好的解决方案。根据您需要的确切数据以及您正在使用的数据,您应该能够在数据库中完成所有工作。