我有一個擁有10億條記錄的MongoDB集合。它最近15天從電信SMSC節點登錄,基本保持SMSC發送的所有短信的遞送狀態。我努力選擇基於DateTime過濾器的數據。它真的很慢。當我嘗試刪除該集合中的記錄塊以刪除超過兩週的日誌時,它也非常慢。從字面上刪除查詢從不結束。說到這一切,我使用的個人電腦是非常平常的臺式機戴爾電腦,它有一個帶有4GB內存的Core i7處理器。任何建議?如何優化和維護一個包含10億條記錄的MongoDB集合?
回答
這是關鍵:
創建索引來支持查詢
限制查詢的結果數減少網絡需求
用突起只返回所需的數據
使用$提示選擇特定索引
使用增量運算符執行運算服務器端
你可以找到一個解釋:https://docs.mongodb.org/manual/tutorial/optimize-query-performance-with-indexes-and-projections/
您可以發佈您的文檔結構?
我懷疑兩件事。首先,對於10億條記錄,我認爲你的RAM非常匱乏。如果你沒有將工作集保存在內存中,MongoDB的性能就會下降。至少,這包括你的索引。但爲了獲得良好的性能,您還應該包含足夠的工作集(即您的數據庫常規訪問的文檔數量,例如,如果您的查詢通常在任何給定時間在一百萬份這些文檔上工作)。即使是一個很小的索引(比如一個_id字段的主索引)對於10億條記錄來說也會遠遠超過4GB。
其次,你確定你有適當的索引?而你的查詢使用你的索引?您似乎希望在時間戳字段中加上索引,以及可能查詢的任何字段(例如,如果您的刪除查詢還包含除時間戳之外的其他搜索字詞)。
我建議的第一步是獲取索引的大小。您可以通過輸入db.collection.stats().indexSizes
在mongo shell中執行此操作。您需要的最小RAM是您的索引大小+您的工作集的一些金額。
一旦你有足夠的RAM,接下來確保你的查詢使用你的索引。您可以使用Mongo的explain()功能查看任何查詢的查詢計劃,並且可以確定您是否實際訪問了索引,或者Mongo是否繞過它們並執行完整的文檔搜索。
如果您已經定義了合適的索引,有足夠的內存來保存您的工作集(索引+您通常訪問的文檔集),並且確信您的查詢正在使用您的索引,那麼可能適合轉向其他策略,如分片。但是考慮到你現在的計算機統計數據(特別是4GB內存),我懷疑你會走上一個很長的路,只是上面列出的第一步。
以下是集合中的示例數據。
樣本數據:
{ 「_id」:的ObjectId( 「56eacd643f8621ca653d5bf3」), 「節點」: 「torsmsc11」, 「MESSAGE_ID」: 「1264F954」, 「CDR_TYPE」:「初始MO 「, 」SUB_TIME「:」2016-03-17 08:59:50「, 」DEL_TIME「:」2016-03-17 08:59:50「, 」OA_ADDR「:NumberLong(」16477392921「), 「PRE_TRANS_OA」:NumberLong(「16477392921」), 「DA_ADDR」:NumberLong(「16472202975」), 「PRE_TRANS_DA」:NumberLong(「16472202975」), 「ORIG_L OCN」:NumberLong( 「161350003000」), 「ORIG_IDNT」:NumberLong( 「3024902」), 「DEST_LOCN」: 「UNKNOWN」, 「DEST_IDNT」: 「UNKNOWN」, 「SEG_NUM」: 「1 1」 , 「DLV_ATT」:0, 「END_POINT」: 「存儲」, 「FINAL_STATE」: 「交付」, 「CDR_TYPE2」: 「MO」, 「DCS」:0 }
我創建這些字段的唯一組合索引:
MESSAGE_ID,CDR_TYPE,SUB_TIME,DEL_TIME,END_POINT
從SSRS(Microsoft的BI工具)運行此查詢:
從mycollection中選擇TOP 1000 *,其中DEL_TIME位於'2016-03-17 08:59:50'和'2016-03-17 09:59之間:50'
根據你的文檔結構和索引,我高度懷疑你的索引沒有被保存在內存中。我建議的三件事:
在mongo shell中輸入db.collection.stats().indexSizes
。這將爲您提供該集合的所有索引的大小(以字節爲單位)。如果這個數字高於你的RAM(實際上,即使它大於2GB,你可能會交換),那麼你的第一步是添加足夠的RAM來保持你的索引在內存中。
二,你確定你需要一個複合索引嗎?也就是說,你是否運行了很多使用所有這些字段的查詢?還是你這樣做只是爲了確保唯一性?如果您的所有查詢都在DEL_TIME字段中,那麼只在該字段上使用簡單索引將會減少您的索引空間要求。
第三,你有解釋()選項運行你的查詢嗎?您需要在mongo shell中直接執行此操作。這會告訴你,如果你的查詢實際上使用索引。看看查詢,我認爲應該是,但是直到你檢查,你纔會知道。
- 1. SQL查詢 - 包含300列和1.2億條記錄的表
- 2. 從包含2億條記錄的表中選擇一些記錄
- 3. 如何用Spark找到最近鄰居的10億條記錄?
- 4. 數據庫含7億條記錄
- 5. 導出數據塊中包含數億條記錄的MySQL表?
- 6. 維護MongoDB集合的順序
- 7. 我如何從mongodb中導出3億條記錄?
- 8. MongoDB:優化搜索多個集合
- 9. 如何優化包含LIKE'%abc%'查詢的160多萬條記錄的MySQL表
- 10. 如何創建一個包含集合
- 11. 在Python中,如何編寫一個包含集合的集合?
- 12. 我如何輸出一個集合#(10)每行一維數組?
- 13. 我想在oracle數據庫中插入10億條記錄
- 14. 如何向擁有10億條記錄的BAM BizTalk表添加新列
- 15. 如何簡化mongodb集合?
- 16. 在mongodb中爲1億條記錄添加新字段
- 17. Java:用於存儲和讀取10億條數據記錄的最佳方法
- 18. Loopback Model Relation:如何在另一個集合中包含集合
- 19. 優化將多個記錄合併到一個記錄中的mysql視圖
- 20. 如何確定一個集合是否包含Python中的另一個集合
- 21. 檢查特定領域的MongoDB集合存在,但不包括一個記錄
- 22. 在MongoDB中對一個集合中的記錄進行分區
- 23. 組合優化 - 枚舉包含給定集合的所有子集
- 24. MongoDB - 指定集合可能只包含一個文檔
- 25. 請幫我優化包含的子查詢僅幾百記錄
- 26. 用monetdb生成1億條記錄
- 27. 批量插入數億條記錄
- 28. 優化選擇查詢得到10×10的記錄形成數百萬條記錄
- 29. 添加記錄和操縱記錄集以包含公式
- 30. 如何保護包含git歷史記錄的文件夾
非常感謝您的意見。在下面發佈樣本數據。 –