2013-01-10 64 views
0

我正在运行一个类似的查询374次,最多367次的时间性能是合理的,但随后返回结果的时间急剧恶化。为什么使用pymongo这个查询在MongoDB中变慢?

我查询的集合存储帖子,其中每个帖子都有一个唯一的ID,并且数据库中会有几个相同帖子的版本。任务是获取每个帖子ID的最后一个版本。该方法是获取一个明确的帖子ID列表,然后为每个帖子ID获取具有最高ObjectID的帖子ID。

这也可以通过聚合框架做,但它与exception: aggregation result exceeds maximum document size (16MB)

此错误是代码:

for oi in obj_ids: #obj_ids is a list of strings containing unique post IDs 
    t1 = time.time() 
    o = col.find({'object_id':oi}).sort('_id', -1).limit(1)[0] 
    t2 = time.time() 

col.find功能是定时的,下面是这个查询的性能如何随着时间而恶化:

364 of 374 in 0.00369000434875s 
365 of 374 in 0.0037579536438s 
366 of 374 in 0.00375485420227s 
367 of 374 in 0.00367307662964s 
368 of 374 in 0.735110998154s 
369 of 374 in 3.09494900703s 
370 of 374 in 5.16561698914s 
371 of 374 in 7.14517307281s 
372 of 374 in 8.3472340107s 
373 of 374 in 8.61702394485s 
374 of 374 in 8.07462406158s 

任何想法发生了什么?

UPDATE 2012年11月1日

使用Python CPROFILE我发现,似乎有一个网络瓶颈

sorted by time

编辑: 拼写

回答

0

该问题与指数有关。我在_id和object_id上创建了一个复合索引,实际上我应该添加一个单独的_id索引和object_id索引。做完这些后,约380分钟的查询在10分钟左右,而不是5分钟。

1

好像你可能RAM耗尽。在linux上,你可以通过$ free -m

检查你的RAM。看看你是否有空闲的RAM。它激起延迟的因素看起来像是你正在碰到磁盘(交换操作)。

如果python是内存管理器,请使用gc模块。

+0

你说得对,它正在交换。但是,为什么如果他们是独立查询,为什么mongo不清除它的缓存? – DavidA

+0

那么,mongo喜欢RAM。它缓存正在使用的页面。但我认为问题不是mongo,而是Python的问题。原因在于,在迭代过程中,光标对象位于内存中。而是在处理游标的循环内部有一个函数调用。 –

+0

我做了你的建议,但应用程序仍然以相同的方式放慢速度。对脚本进行分析显示,大部分时间都花在'_socket.socket.recv'中(请参阅截图)因此,瓶颈似乎是网络。 – DavidA

0

如果要使用聚合框架,并且“聚合结果超过最大文档大小(16MB)”错误,则可以使用$ out语句将结果放入临时集合中,然后重新执行该集合的结果。如果您的收藏中有大量元素,这可能会更快,因为您最终会减少查询次数,从而减少网络延迟。