为什么这个查询使用pymongo在MongoDB中减速?

时间:2013-01-10 14:07:31

标签: performance mongodb networking pymongo

我正在运行类似的查询374次,直到第367次性能合理,但随后返回结果的时间急剧恶化。

我查询的集合存储每个帖子具有唯一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

任何想法发生了什么?

更新2012/11/01

使用Python cprofile我发现似乎存在网络瓶颈

sorted by time

编辑: 拼写

3 个答案:

答案 0 :(得分:1)

好像你可能用完了RAM。在linux上,您可以通过$ free -m

检查您的RAM

查看您是否有空闲内存。它飙升延迟的因素似乎是你正在击中磁盘(交换操作)。

如果python是内存耗尽,请使用gc模块。

答案 1 :(得分:0)

问题与指数有关。我在_id和object_id上创建了一个复合索引,实际上我应该添加一个单独的_id索引和object_id索引。执行此操作后,~380个查询在大约10秒内运行,而不是5分钟。

答案 2 :(得分:0)

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