2015-11-29 58 views
0

我正在做一個包含超過100百萬個文檔的集合。MongoDB:索引在100多個mio文檔上很慢

我的查詢是:

{ 
"domain": domain, 
"categories" : "buzz", 
"visit.timestamp" : { "$gte": date_from, "$lt": date_to }, 
} 

我僅投影_id

我有一些指標就可以了,比如,每例如:

{ "visit.timestamp": -1 } 

和複合索引,如:

{ "visit.timestamp": -1, "domain": 1, "categories" : 1 } 

基於計數,每個例子中,30最後幾天給出的結果〜 30秒。 的explain()讓我發現,查詢中使用最簡單的指標:{ "visit.timestamp": -1 }

所以我試圖強迫其他順序複合索引:

{ "categories" : 1, "domain": 1, "visit.timestamp": -1 } 
{ "domain": 1, "categories" : 1, "visit.timestamp": -1 } 

隨後,查詢使用其中的一個,但結果需要更長的時間:第一種情況下約60秒,另一種情況下,超過241秒!

注1:這與聚合框架的結果是一樣的,但並不奇怪。

注2:「visit.timestamp」是一個ISODate。每個文檔比前一個文檔更新。

注意3:該計數返回約140萬個文件(在〜105百萬之間),但檢查了12百萬個文檔(見下文)。

問:

1 /我不知道爲什麼一個查詢中使用應該覆蓋它完全索引時需要更長的時間。你有解釋嗎?

2 /您有任何提示來改善此查詢的響應時間嗎? 的explain()表明該查詢看了看:

"totalKeysExamined": 12628476, 
"totalDocsExamined": 12628476, 

因爲,我可以理解,該指數只覆蓋日期索引visit.timestamp等所有文檔的時間框架內,已經進行審查。

回答

1

第二個問題:

  1. 確保問題在MongoDB的範圍。將其與應用程序代碼和I/O隔離。通過在本地連接(一個)MongoDB服務器來執行查詢。
  2. 本地發生?檢查服務器的CPU和磁盤運行狀況。
  3. CPU(s)和磁盤都不合適嗎? Make sure your index fits in to RAM。來自MongoDB的FAQ:

如果索引不適合RAM,會發生什麼?

當一個索引是太大而不適合到RAM中,必須的MongoDB從磁盤讀取的 指數,這比從 RAM讀取慢得多的操作。請記住,當您的服務器有可用於該索引的RAM 與working set的其餘部分結合時,索引適合RAM。

在某些情況下,索引不需要完全適合RAM。有關 的詳細信息,請參閱Indexes that Hold Only Recent Values in RAM

第一個問題:

也許你的索引不適合到RAM中。並且使其複合可能會增加對磁盤的I/O操作次數。雖然我不是MongoDB專家。

+0

2.1:我確定,因爲我在Mongoshell中進行測試:)。但是你回答關於索引適合內存可能會有所幫助,I4m不習慣看這個,因爲服務器擁有大部分時間足夠的內存(128G)並且只能與SSD一起運行,但它看起來最糟糕。我稍後會回來確認並確認答案是正確的:)謝謝。 –

+0

我在沙箱上的測試似乎證實索引不適合RAM。 –