2015-06-20 137 views
3

我在集合中添加了一個索引。我推出的第一個查詢比沒有索引的查詢慢。以下是沒有索引的那些更快,所以這是有道理的。創建索引後的第一個查詢很慢

我想知道爲什麼會出現這種情況,是因爲索引必須從磁盤轉到內存?然後,我更加難以理解的是,我放棄了索引,重新啓動了mongod,我又重新創建了索引,它的速度很快,不像第一次。如果我重新啓動計算機的行爲類似於第一次,所以它只會在索引的第一次緩慢運行。

有人能清楚地解釋這種行爲嗎?

以下我給出一些關於文檔,索引和查詢信息的信息。集合內的文件看起來像:

> db.posts.findOne() 
{ 
     "_id" : ObjectId("557d73e1fab73211b00f3080"), 
     "title" : "aaa", 
     "author" : "nuevo", 
     "body" : "aaa", 
     "permalink" : "aaa", 
     "tags" : [ 
       "a" 
     ], 
     "comments" : [ ], 
     "date" : ISODate("2015-06-14T12:30:25.733Z") 
} 

集合的大小:

> db.posts.find().count() 
1008 

查詢沒有索引,它需要3毫秒(我不把所有的輸出解釋,只有相關部分):

> db.posts.explain("executionStats").find({ permalink: "ambzrbxvnorazgnqvzbw"}); 

{ 
.... 
     "executionStats" : { 
       "executionSuccess" : true, 
       "nReturned" : 1, 
       "executionTimeMillis" : 3, 
       "totalKeysExamined" : 0, 
       "totalDocsExamined" : 1008, 
.... 
} 

創建索引:

> db.posts.createIndex({permalink:1}) 
{ 
     "createdCollectionAutomatically" : false, 
     "numIndexesBefore" : 3, 
     "numIndexesAfter" : 4, 
     "ok" : 1 
} 

查詢索引創建(71毫秒):

> db.posts.explain("executionStats").find({ permalink: "ambzrbxvnorazgnqvzbw"}); 

{ 
.... 
     "executionStats" : { 
       "executionSuccess" : true, 
       "nReturned" : 1, 
       "executionTimeMillis" : 71, 
       "totalKeysExamined" : 1, 
       "totalDocsExamined" : 1, 
.... 
} 

下重新啓動與其他永久鏈接相同的查詢,以避免從存儲器(或類似的東西)開它。它需要0毫秒:

> db.posts.explain("executionStats").find({ permalink: "orrjnueekntvjegzvbjk"}); 

{ 
.... 
     "executionStats" : { 
       "executionSuccess" : true, 
       "nReturned" : 1, 
       "executionTimeMillis" : 0, 
       "totalKeysExamined" : 1, 
       "totalDocsExamined" : 1, 
.... 
} 

回答

2

你在Linux上? Linux將所有可用內存用作磁盤緩存。即使在你重新啓動mongo之後,緩存會一直存在,直到系統需要其他東西。即使沒有分支,查詢命中緩存的查詢速度也會很快 - 因爲它們打到內存。 有一些命令可以確認 - 檢查緩存命中和未命中。不管讀取的數據量有多少,驅動器緩存,內存緩衝區等等都會提前讀取兆字節,因此無緩衝讀取(必須打開硬盤驅動器上的盤片)需要比讀取內存更長的時間即使你對單字節感興趣)。

有關實際數字,請參見https://gist.github.com/jboner/2841832

我認爲如果你考慮 http://docs.mongodb.org/manual/administration/analyzing-mongodb-performance/#administration-monitoring-page-faultshttp://docs.mongodb.org/manual/reference/glossary/#term-page-fault ,你將能夠確認訪問速度慢基本上是100%頁面錯誤(一切都需要從硬盤讀取),其中快速的訪問將是接近100%命中(緩存讀取)。

+0

不,我正在使用Windows 8,64位 – Weslor

+1

我非常確定Windows也使用物理內存作爲磁盤緩存。我認爲它是任務管理器,性能選項卡中顯示的「緩存」內存。 所以一般的想法和Linux一樣。 –