iT邦幫忙

3

關於 MongoDB 性能優化:從診斷問題到解決方案的經驗分享

  • 分享至 

  • xImage
  •  

image

前言

作為資料庫管理的新手小白,在 MongoDB 應用方面實在沒什麼經驗,採用 MongoDB 也只是為了方便儲存不對稱數據的優勢,然而使用到現幾個月了逐漸發現效能堪憂,於是開始了我的性能調校之路!

情境描述

在處理 AWS 帳單數據的 MongoDB 系統中,我們遇到了查詢效能緩慢的問題,系統需要頻繁地根據帳單期間(BillingPeriodStartDate)和帳戶 ID(UsageAccountId)來查詢數據,單一 collection 數據量已達到約 300 萬筆記錄。

問題診斷

1. 初始查詢分析

首先,我的需求是使用以下查詢來檢索特定帳期和帳戶的數據:

db.rawdata.find({ 
    "lineItem/UsageAccountId": { 
        $in: [
            "123456789001", "123456789002", "123456789003",
            // ... 更多帳戶 ID
        ] 
    }, 
    "bill/BillingPeriodStartDate": "2024-11-01T00:00:00Z" 
})

2. 使用 explain() 診斷查詢效能

通過添加 explain("executionStats") 來分析查詢執行情況:

db.rawdata.find({...}).explain("executionStats")

優化前的執行統計:

{
    "executionStats": {
        "executionSuccess": true,
        "nReturned": 133696,
        "executionTimeMillis": 8547,
        "totalKeysExamined": 0,
        "totalDocsExamined": 3109528,
        "executionStages": {
            "stage": "COLLSCAN",
            // ... 省略其他細節
        }
    }
}

關鍵問題指標:

  1. executionTimeMillis: 8547 (查詢耗時近 8.5 秒)
  2. stage: "COLLSCAN" (進行了全集合掃描)
  3. totalDocsExamined: 3109528 (掃描了大量文檔)
  4. totalKeysExamined: 0 (沒有使用索引)

解決方案

1. 創建複合索引

根據查詢需求,我創建了一個複合索引:

db.rawdata.createIndex({
    "bill/BillingPeriodStartDate": 1,
    "lineItem/UsageAccountId": 1
})

2. 驗證索引創建

確認索引是否成功創建:

db.rawdata.getIndexes()

3. 重新執行查詢分析

使用相同的 explain 命令檢查優化效果:

db.rawdata.find({...}).explain("executionStats")

優化後的執行統計:

{
    "executionStats": {
        "executionSuccess": true,
        "nReturned": 133696,
        "executionTimeMillis": 1247,
        "totalKeysExamined": 133730,
        "totalDocsExamined": 133696,
        "executionStages": {
            "stage": "FETCH",
            "inputStage": {
                "stage": "IXSCAN",
                // ... 省略其他細節
            }
        }
    }
}

效能改善分析

通過對比優化前後的關鍵指標:

  1. 查詢耗時:

    • 優化前:8547 毫秒
    • 優化後:1247 毫秒
    • 改善幅度:約 85%
  2. 掃描文檔數:

    • 優化前:3,109,528 文檔
    • 優化後:133,730 文檔
    • 減少幅度:約 95%
  3. 查詢方式:

    • 優化前:COLLSCAN(全集合掃描)
    • 優化後:IXSCAN(索引掃描)

小結

本文透過 explain() 分析查詢效能低落的癥結點,並建立有效索引,達到巨幅提升查詢的效能,但這僅僅只是調優的一小部分,我目前還遇到其他問題尚未解決,在問題解決以後,會再跟大家分享,請各位敬請期待!


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言