Performance

MongoDB性能問題

  • September 4, 2014

我有一個 MongoDB 用於儲存這樣的結果

{_id, type, imei, lat, lng, spd, dir, time}
{_id, type, imei, lac, cid, time}

如果typef第一個則使用,如果是l第二個則使用。

這是索引:

"indexSizes" : {
   "_id_" : 340358704,
   "imei_1" : 614508160,
   "type_1" : 183616608,
   "type_1_imei_1" : 349793808
},

Collection 有大約 1000 萬份文件。我有很多關於typeandimei的查詢,目前只有類型f在應用程序中使用。

這是日誌文件中的一行

Sun Aug 31 19:14:39.402 [conn782250] query xxyyxx.locs query: { $query: { $and: [ { imei: "359710042581612" }, { type: "f" } ] }, $orderby: { time: -1 } } ntoreturn:1 ntoskip:0 nscanned:140455 scanAndOrder:1 keyUpdates:0 numYields: 59 locks(micros) r:38456361 nreturned:1 reslen:159 19727ms

這花了大約20秒,太多了。

我需要進一步優化我的收藏。這在 Web 應用程序中使用,有時像這樣的查詢會執行 10imei秒,大約需要 200 秒,這可能會導致超時。這是非同步執行的(ajax),但仍然有太多的等待時間。

這裡的專家的任何幫助都非常受歡迎。

另外,如果您認為我遺漏了什麼,請務必索取更多資訊。

提前致謝

順便說一句,我將 PHP 用於 Web 元件(Laravel 框架和https://github.com/jenssegers/Laravel-MongoDB

編輯:這是explain(已刪除)

EDIT2:創建更好的索引後:

MongoDB shell version: 2.4.9
connecting to: test
> use gpstracker
switched to db gpstracker
> db.locs.stats()
{
   "ns" : "gpstracker.locs",
   "count" : 10137188,
   "size" : 1400944384,
   "avgObjSize" : 138.19852053646434,
   "storageSize" : 1580060672,
   "numExtents" : 19,
   "nindexes" : 2,
   "lastExtentSize" : 415145984,
   "paddingFactor" : 1,
   "systemFlags" : 0,
   "userFlags" : 0,
   "totalIndexSize" : 826806176,
   "indexSizes" : {
       "_id_" : 359997456,
       "type_1_imei_1_time_-1" : 466808720
   },
   "ok" : 1
}
> db.locs.find({ $and: [ { imei: "359710042581612" }, { type: "f" } ] }).explain()
{
   "cursor" : "BtreeCursor type_1_imei_1_time_-1",
   "isMultiKey" : false,
   "n" : 150158,
   "nscannedObjects" : 150158,
   "nscanned" : 150158,
   "nscannedObjectsAllPlans" : 150158,
   "nscannedAllPlans" : 150158,
   "scanAndOrder" : false,
   "indexOnly" : false,
   "nYields" : 329,
   "nChunkSkips" : 0,
   "millis" : 128173,
   "indexBounds" : {
       "type" : [
           [
               "f",
               "f"
           ]
       ],
       "imei" : [
           [
               "359710042581612",
               "359710042581612"
           ]
       ],
       "time" : [
           [
               {
                   "$maxElement" : 1
               },
               {
                   "$minElement" : 1
               }
           ]
       ]
   },
   "server" : "CDSX001:27017"
}

您的查詢正在使用索引來獲取結果,但之後需要對它們進行排序,這是一項昂貴的操作。

“scanAndOrder” : true,scanAndOrder 是一個布爾值,當查詢不能使用索引中文件的順序返回排序結果時為 true:MongoDB 必須在從游標接收文件後對文件進行排序。

解決方案是在 {imei:1, type:1, time:-1} 或 {type:1, imei:1, time:-1} 上應用索引(索引上的 imei,type 順序取決於 imei 和類型選擇性)

引用自:https://dba.stackexchange.com/questions/75382