Mysql Rails在查询结果上的位置
我有一个模型-Mysql Rails在查询结果上的位置,mysql,ruby-on-rails,ruby,ruby-on-rails-3,Mysql,Ruby On Rails,Ruby,Ruby On Rails 3,我有一个模型-链接,它有很多点击率。我试图做的是从一个数据库表中聚合每小时点击次数的数据-点击次数,包括年,月,日,和小时 一切正常,但当我运行下面的代码时,我在数据库上的查询几乎达到了1000次,这似乎太过分了 #before iteration @hits = @link.hits.group('year, month, day, hour') .order('year ASC, month ASC, day ASC, hour ASC') .select('year, month,
链接
,它有很多点击率。我试图做的是从一个数据库表中聚合每小时点击次数的数据-点击次数
,包括年
,月
,日
,和小时
一切正常,但当我运行下面的代码时,我在数据库上的查询几乎达到了1000次,这似乎太过分了
#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
是一个Time
对象,自第一次点击接收到的链接以来,它以1小时的步长进行迭代
我认为rails将存储查询结果,而不是每次都重新查询。我也找不到任何关于缓存查询结果的东西。是我完全错过了什么,还是这真的是最简单的方法
下面是查询的示例(这是我在日志中看到的,以一千块为单位):
嗯。因此,
@hits
将是一个ActiveRecord::Relation对象,本质上是一个SQL查询。我相信,因为每次迭代都使用不同的参数调用。where
,从而改变查询,Rails决定每小时都必须重新运行查询
最简单的修复方法可能是在迭代之前将关系“折叠”到数组中,然后每次使用纯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)
不过,我认为这实际上不太可能是最好的解决方案。根据您需要的数据以及您正在使用的数据,您应该能够在数据库中完成所有工作。1000个查询要求什么?是否可以通过快速加载关联来改善这一点?没有正在加载的关联。它只需要在链接创建后每小时运行一次(现在大约3周)。我将在问题中添加一个查询示例。我知道我遗漏了一些内容。非常感谢。就像你说的,这可能不是最好的解决方案,所以我会等着接受答案。如果在一天结束前没有更好的,你肯定会得到它。@Jon谢谢。我想亲自尝试一下“更好”的解决方案,但我清楚地记得,分组是mysql最不像postgres的地方之一(我的数据库专业知识就在这里)。我的答案也是一样的。如果有更好的解决方案,这取决于您希望进行这些查询的次数。我是说,缓存如何获得更多的点击率?
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)