我有这个方法,使用find_by_sql返回每个来源的10条最新记录
def latest_results
Entry.find_by_sql(["
select x.id,x.created_at,x.updated_at,x.source_id,x.`data`,x.`uuid`,x.source_entry_id
from
(select t.*,
(@num:=if(@group = `source_id`, @num +1, if(@group := `source_id`, 1, 1))) row_number
from (
select d.id,d.created_at,d.updated_at,d.source_id,d.`data`,d.`uuid`,d.source_entry_id
from `streams` a
JOIN `stream_filters` b
on b.stream_id=a.id
JOIN `filter_results` c
on c.filter_id=b.id
JOIN `entries` d
on d.id=c.entry_id
where a.id=?
) t
order by `source_id`,created_at desc
) as x
where x.row_number <= 10
ORDER BY x.created_at DESC
",self.id])
end
它在有限记录的本地环境中正常工作。 我有t2.micro,它有2个Gib内存来服务应用程序。现在这个查询耗尽我的整个记忆和应用程序得到frizzing。 任何建议我怎样才能做得更好?我想在不增加机器尺寸的情况下解决这个问题。
答案 0 :(得分:1)
我曾遇到过类似的问题。尽管很难优化,但mysql变量的解决方案看起来很整洁。在您的情况下,似乎正在进行全表扫描。
我建议您首先获取要显示的来源。然后运行第二个查询,其中包含多个前10个选项,每个源一个,所有都与联合组合。
联合前10名选择将有一些重复声明,您可以使用ruby轻松自动生成。
# pseudo code
sources = Entry.group(:source).limit(n)
sql = sources.map do |source|
"select * from entries where source = #{source} order by created_at limit 10"
end.join("\nunion all\n")
Entry.find_by_sql(sql)