我有一個擁有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. 數據庫含7億條記錄
- 4. MongoDB:優化搜索多個集合
- 5. 如何優化包含LIKE'%abc%'查詢的160多萬條記錄的MySQL表
- 6. 我如何輸出一個集合#(10)每行一維數組?
- 7. 我想在oracle數據庫中插入10億條記錄
- 8. 如何向擁有10億條記錄的BAM BizTalk表添加新列
- 9. 如何簡化mongodb集合?
- 10. Loopback Model Relation:如何在另一個集合中包含集合
- 11. 在MongoDB中對一個集合中的記錄進行分區
- 12. MongoDB - 指定集合可能只包含一個文檔
- 13. 用monetdb生成1億條記錄
- 14. 批量插入數億條記錄
- 15. 克隆現有記錄集以優化記錄集
- 16. 如何保護包含git歷史記錄的文件夾
- 17. Silverlight + WCF RIA +如何包含一組有條件的子記錄(不是所有的都是集合)
- 18. MongoDB維護
- 19. 在一列中包含多個條目的數據庫記錄
- 20. 即使一天獲得1條記錄也包含2條不同的記錄
- 21. 如何優化運行數百萬條記錄的SQL Server合併語句
- 22. 如何獲得最後10條記錄
- 23. 最後一個連接表的記錄(如何優化)
- 24. 如何維護單個文件中的魚類功能集合?
- 25. 如何檢測一組集合是否包含另一個集合?
- 26. MongoDB:性能優化:聚合管道(一個集合)VS聚集加上附加查詢分離集合
- 27. MongoDB子文檔中的密鑰的不同值(1億條記錄)
- 28. 單個集合在mongoDb中可以包含多少個文檔?
- 29. MongoDB mongorestore和現有的記錄收集
- 30. postgresql:xml解析:xpath只返回一條記錄,其中xml包含3條記錄
非常感謝您的意見。在下面發佈樣本數據。 –