2013-01-10 105 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語句將結果放入臨時集合中,然後重新執行該集合的結果。如果您的收藏中有大量元素,這可能會更快,因爲您最終會減少查詢次數,從而減少網絡延遲。