2012-05-31 94 views
0

我現在有一個長時間運行的操作(在Python +芹菜運行),通過約4300萬元素的整個蒙戈集合去和做的元素的分析,而不進行任何更改這些元素。拆分蒙戈集合(由Index)

由於此彙集成長的操作已經開始花費較長時間(明顯),現在是週期性失敗通常是由於超時到不同的數據庫。

我想這個操作拆分成若干小規模的行動 - 也許就只有幾百萬元經營 - 我想知道即將產生,將做拆分查詢的最佳方式。我只有一個索引在這個集合和它的_id

顯而易見的答案似乎是這樣的:

# This is executed in parallel on different servers 
def doAnalysis(skipped,limit) 
    db.<collection>.find().skip(skipped).limit(limit) 

... 

# This is the parent task 
elemsToAnalyze = db.<collection>.find().count()/10; 
for i in range(0,10: 
    doAnalysis(elemsToAnalyze * i, elemsToAnalyze) 

但事實證明,在.skip()需要時間 - 基本上就像是其實早就進行分析!有一個更好的方法嗎?

回答

1

skip()可以在這種情況下很慢。您可以使用該批次的最後一個_id來查詢下一批次,而不是使用範圍查詢。例如:

db.<collection>.find({ "_id" : { $gte: prev_batch_last_id } }).sort({ _id : 1 }).limit(limit); 

您必須自己將批次的最後一個ID存儲到變量中。

+0

感謝您的回覆。這種方法的麻煩是我需要知道*先前執行的批處理中的last_id。最好是,我希望能夠獨立運行這些進程,以便它們不需要共享數據 - 好處是它們可以並行化。 –

+0

這個集合是否分割?如果是這樣,您可以使用塊邊界來分割集合。如果沒有,還有其他方法可以在你的集合中劃分_id的範圍。 – matulef

+0

@ChrisW基於你的示例conde,我認爲不需要並行處理。你有多個數據庫嗎?如果你這樣做,就像matulef提到的那樣,你可以使用分片邊界(如果分片)。如果您爲每個元素執行的任務非常短,則爲一個數據庫並行執行查詢可能不會加快處理速度,因爲db一次只能處理一個查詢。如果並行方式實際上更快,您可以先嚐試(手動)。 – Lycha