2013-01-07 28 views
3

我正在使用Doctrine MongoDB ODM從遠程MongoDB數據庫中獲取少量文檔。爲什麼在實際查詢只花費幾毫秒時,MongoDB結果很慢?

我確認查詢只用了1ms找到約12個匹配的文檔。 (即解釋輸出中的「millis」:1)。但迭代結果花費了大約250毫秒。

我不能得到任何性能增益,當我試圖下列選項

  • 選擇( '名稱')
  • 水合物(假)
  • eagerCursor(真)
  • 限組合(1)

我該如何最小化這種延遲?


UPDATE:更多的解釋與示例代碼

$qb = $dm->createQueryBuilder('Books'); 
$books = $qb->select('name') 
      ->field('userId')->equals(123) 
      ->field('status')->equals('active') 
      ->eagerCursor(true) // Fetch all data at once 
      ->getQuery() 
      ->execute(); 

/** 
* Due to using Eager Cursor, the database connection should be closed and 
* all data should be in memory now. 
*/ 

// POINT A 
foreach($books as $book) { 
    // I do nothing here. Just looping through the results. 
} 
// POINT B. 

/** 
* From POINT A to POINT B takes roughly 250ms when the query had 12 matching docs. 
* And this doesn't seem to be affected much by the number of records matched. 
* As the data is already in the memory, I expected this to be done in range of 
* 5~10ms, not 250ms. 
* 
* Am I misunderstanding the meaning of Eager Cursor? 
*/ 
+0

什麼是查詢?是否只涉及一個集合? – Thilo

+0

是的,只有一個集合。基本上我正在獲取匹配{userId:123,status:'active'}的記錄。我已經有了這些字段的索引。 {userId:1,status:1} – Jaepil

+0

如果您跳過ODM並通過Mongo控制檯進行查詢和迭代,會發生什麼情況? – 2013-01-07 10:02:32

回答

0

好吧,看起來我誤解了Eager光標的意思。

http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/eager-cursors.html 該文獻表明,當執行()稱爲所有結果被檢索到存儲器中。但這並不準確。相反,我發現第一次訪問EasgerCursor時記錄被抓取。

在EagerCursor的初始化()功能,正常蒙戈光標的實例檢索,並最終傳遞到iterator_to_array()函數通過一些其他的功能去後。我很確定這是Mongo Driver在取回記錄時的真實工作。

在我的情況下,這發生在foreach循環中。因此,在A點和B點之間觀察到延遲。爲了證實這一點,我嘗試了MongoClient實現,發現實現之間的總體時間非常接近。

謝謝大家的幫助。

0

有這裏感興趣的兩個區間:一個是從代碼開始到A點;第二個是從A點到B點。由.explain()測量的是前者;你測量的是後者。

特別是,一旦BSON文檔已經傳輸到客戶端(您的PHP程序),他們仍然需要反序列化並轉換爲PHP對象。如果您使用的是Doctrine,則必須執行額外的處理。

你看到的時間是反序列化過程的時間。這些文件有多大?文檔的全部內容必須反序列化:如果這些內容很大或很複雜(深嵌套,很多數組等),那麼這可能需要一些時間。

您只需獲取所需的字段即可縮短反序列化時間。如果向查詢中添加 - > select('_ id'),則循環時間應快得多。

+0

如示例代碼所示,我已經只選擇了一個字段,僅返回約12個文檔。反序列化這些文檔應該是即時的。 – Jaepil