Mysql Rails选择每组前n条记录(内存泄漏)

Mysql Rails选择每组前n条记录(内存泄漏),mysql,ruby-on-rails,Mysql,Ruby On Rails,我有一个方法,使用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(@g

我有一个方法,使用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内存来为应用程序服务。现在,这个查询耗尽了我的全部内存,应用程序变得烦躁不安。
有什么建议我怎样才能做得更好?我想在不增加机器尺寸的情况下解决这个问题

我曾经有过类似的问题。使用mysql变量的解决方案一开始看起来很整洁,但很难优化。在您的案例中,似乎正在进行全表扫描

我建议先获取要显示的源代码。然后运行第二个查询,其中包含多个前10个选择,每个源一个,所有选择都与一个联合相结合

union top 10 select将有一些重复语句,您可以使用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)

第二条线在做什么?你为什么在那里设10个限制?我认为源代码应该包含所有源代码,并通过一个循环将所有前10个实体捆绑在一起,这可能会解决内存泄漏问题,但我不确定性能。它有多快?我刚刚举了个极限10的例子。因为如果你有很多来源。可能您也不应该在一个页面中全部显示它们。虽然问题不是mysql,而是rails的渲染。对于日期和源类型的适当索引,MySQL应该能够在几秒钟内处理数百万条记录,并且如果您真的需要渲染所有的源,则不需要存储内存,这将导致大量的记录,我还将考虑使用“ActhVercord::Base.Copy.Exc执行”的原始SQL查询。它不会为每个条目创建活动记录对象,这将节省大量内存。我们有一个类似的案例,其中一些报表查询需要5秒,但渲染超过10万条记录需要几分钟。更好的策略是分页或区块加载,这是一个API端点。答案将是json,所以我认为问题不在于渲染,我使用react来渲染数据。