2017-04-13 114 views
0

我有位置收集與索引timestamp_1, timestamp_2 and user_id字段。執行查詢時(您可以在以下日誌中看到),然後查詢〜3分鐘(175670ms)。我不承認它爲什麼會發生! 我附加了下面的MongoDB-Log。
任何人都可以解釋我下面的日誌,我怎麼能優化它?說明MongoDB日誌輸出

2017-04-12T17:04:33.759 + 0000我COMMAND [conn167]查詢 位置的集合查詢:{的OrderBy:{timestamp_1:1},$查詢:{ $和:[{timestamp_1: {$ lte:1492016294486.0}},{timestamp_2:{ $ gte:1491993563400.0}},{user_id:「jkfjlsjfflki-14asddsd」}]}} planSummary:IXSCAN {user_id:1},IXSCAN {user_id:1} ntoreturn :1000 ntoskip:0 keysExamined:27254 docsExamined:27254 hasSortStage:1 cursorExhausted:1個keyUpdates:0 writeConflicts:0 numYields:3350 nreturned:67個reslen:176574把鎖:{全球:{ acquireCount:{R:6702}},數據庫:{acquireCount:{r: 3351}}, 收藏:{acquireCount:{R:3351}}} 175670ms

一個問題:我創造我自己的 「_id」 字段,以便任何缺點,這樣的價值?我創建的只是字符串值,並期待mongoDb索引它沒有任何問題。

2017-04-12T17:04:41.979 + 0000我COMMAND [conn150]查詢db.users 查詢:{的OrderBy:{_id:1},$查詢:{_id: 「USR-dfhsddf- 14905426shfkjdhf」}} planSummary:IDHACK ntoreturn:1 ntoskip:0 keysExamined:1 docsExamined:1 idhack:1 cursorExhausted:1個 keyUpdates:0 writeConflicts:0 numYields:0 nreturned:1 reslen:1291把 鎖:{全球:{acquireCount :{R:2}},數據庫:{acquireCount: {R:1}},集合:{acquireCount:{R:1}}} 2627ms

在此先感謝!

回答

0

先回答第二個問題 - 對_id使用自己的值是很好的。 MongoDB將正確索引它。這樣做的結果是,現在你的應用程序負責確保沒有重複。

默認的MonogDB ObjectId類型還包含值中的時間戳。這意味着,當_id字段是ObjectId時,通過插入順序(或創建ObjectId時的技術時間戳)返回結果。

至於日誌輸出,查詢性能輸出值來自Database Profiler。您可以在https://docs.mongodb.com/manual/reference/database-profiler/處看到值列表。

查詢性能非常有用的工具是explain()https://docs.mongodb.com/manual/reference/method/cursor.explain/https://docs.mongodb.com/manual/reference/explain-results/。您將不得不在自己的系統上測試查詢的性能。

看起來好像您在各個字段上收集了三個不同的索引:timestamp_1,timestamp_2user_id

查詢是比較三個字段:

  • timestamp_1小於值
  • timestamp_2比的值
  • user_id更大等於值

您也可以通過訂購輸出中的timestamp_1字段。

planSummary: IXSCAN { user_id: 1 }, IXSCAN { user_id: 1 }是說明該查詢規劃是選擇指數user_id的查詢,然後選擇在user_id指數再次用於排序,這是不是你真正想要排序的字段。有關參考,請參閱https://groups.google.com/forum/#!topic/mongodb-user/nQlmVdODo-M

keysExamined:27254意味着索引掃描在索引檢查27254個密鑰。 docsExamined:27254意味着MongoDB從磁盤上提取了27245個文檔來檢查內容。 nreturned:67指出查詢的結果返回了67個文檔。掃描user_id索引,找到27254匹配,然後從集合中檢索每個文檔。這些文件被解析並且timestamp*字段被比較,並且返回67個匹配的記錄。不使用timestamp_1timestamp_2索引。

MongoDB的存儲索引作爲B樹和確實允許化合物索引(https://docs.mongodb.com/manual/indexes/)。您可以測試製作索引的新組合,分析結果,並查看哪個最適合您的應用程序。與所有三個領域的一個複合索引將允許查詢分析所有隻使用索引,應該減少的MongoDB需要從磁盤讀取的文件數量的查詢字段(user_idtimestamp_1timestamp_2)的。一個可能的例子是:

db.collection.createIndex({user_id:1, timestamp_1:1, timestamp_2:-1) 

該指數將允許蒙戈查詢規劃相匹配的user_id場,然後找到結果,其中timestamp_1小於價值,然後找到更多的結果,其中timestamp_2比它的價值更大。因爲timestamp_1timestamp_2之前列出,匹配記錄已經排序,這也可能允許MongoDB跳過排序階段。你需要在你自己的系統上測試它來驗證它的性能更好。根據集合中文檔的基數,您可以嘗試將時間戳字段放在user_id字段的前面。