新手问题 MongoDB 批量查询性能优化问题

mumuxizzz · 发布于 2017年10月11日 · 最后由 mumuxizzz 回复于 2017年10月12日 · 589 次阅读
96

项目中某行代码( map迭代 )执行时占用CPU资源到90%多。 代码如下:

users = (uids.map {|uid| MasterFriend.find(uid)}).to_a

uids是一个大小为6000多的数组,里面存放的user表的id字段(mongoid自带的_id字段)

这个迭代查询总耗时在5s以上,mongoid默认_id字段是加了索引的。MasterFriend表不到10000条记录。

请教如何优化?👼


发现了新的问题,如上获得的users数组里面存放了很多个document对象(约为5000)。然后我发现这种情况下,我去遍历这个数组,对每个document对象调用其encode方法(就是把输出为json格式),这个时候耗时更加严重。

def encode
  {
      id: self.id.to_s,
      images: images.first,
      gender: gender
  }
end

第一种遍历(严格意义上算不上遍历):

users.map :&encode

第二种遍历:

arr=[]
users.each do |u|
  arr << u.encode
end

发现第二种遍历方式比第一种执行速度要慢1倍。执行这两段代码的时候cpu都飙到90%多了。而且假如我直接把users数组赋值给另外一个数组,直接内存泄露了。🙁

我是一边在rails console中执行,一边开着另外一个窗口用top命令实时查看的。

请教一下,ruby里面的迭代就这么耗时吗?数组存放太多数据是否也不合适?如何避免内存泄露的问题?

共收到 10 条回复
96

什么页面需要一下次取几千条数据出来?

11524

😂 我想起来很久以前我也是不知道where和find可以直接传数组什么的 谷歌

96
32ad583255925 回复

是API,倒是分页返回的。但是做法是先全部查到,然后分成很多份。需要第x页就返回第x份。不过这样倒提醒我了,我这样做是挺笨的,应该需要第多少页就查第几页数据。thanks

96
32ad583255925 回复

这个我知道的, 但是不知道查询效率上会带来多少提升。我试一试。😇

775

为什么不一次取出?

96
775nouse 回复

没懂您的意思。我后来参照@gyorou的方法,这样执行查询:

users = MasterFriend.where(_id: { '$in': uids}).to_a

这样子比我最初的做法就快了很多。

075528
  1. 就是上面你使用的,查询数据库的时候,可以直接传数组,没必要一条一条查。
  2. 分页可以直接用数据库做,不要全部查出来再分页吧。 比如下面的语句
"SELECT  `users`.* FROM `users` LIMIT 20 OFFSET 0"
96

在ruby-china这样和谐的社区,我觉得我变得平静了很多,看到这样的问题,我都能欣然接受了

De6df3

类似

where id in (?)
96

已解决, 改变了处理分页的逻辑.

32 mumuxizzz 关闭了讨论 10月12日 16:38
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册