績效的最佳做法

使用此資訊將最佳實作應用於您在 IBM Cloud 上執行的 Databases for MongoDB 部署。

效能疑難排解流程圖

使用流程圖來決定如何排除效能故障,以及下一步要採取的步驟。

┌─────────────────────────────────┐
│   Performance issue detected    │
└────────────┬────────────────────┘
             │
             ▼
┌─────────────────────────────────┐
│  Check IBM Cloud Monitoring     │
│  - CPU > 80%?                   │
│  - Memory > 80%?                │
│  - Disk latency high?           │
└────────────┬────────────────────┘
             │
        ┌────┴────┐
        │  YES    │
        ▼         │
┌──────────────┐  │
│ Scale        │  │
│ resources    │  │
└──────────────┘  │
                  │ NO
                  ▼
        ┌─────────────────────┐
        │ Check slow queries  │
        │ db.system.profile   │
        └─────────┬───────────┘
                  │
             ┌────┴────┐
             │  Found? │
             ▼         │
        ┌─────────┐    │
        │ Optimize│    │
        │ queries │    │
        │ & indexes│   │
        └─────────┘    │
                       │ NO
                       ▼
              ┌────────────────┐
              │ Check Locks    │
              │ currentOp()    │
              └────────┬───────┘
                       │
                  ┌────┴────┐
                  │ Locked? │
                  ▼         │
             ┌─────────┐    │
             │ Kill or │    │
             │ optimize│    │
             └─────────┘    │
                            │ NO
                            ▼
                   ┌────────────────┐
                   │ Check cache    │
                   │ hit ratio      │
                   └────────┬───────┘
                            │
                       ┌────┴────┐
                       │ < 95%?  │
                       ▼         │
                  ┌─────────┐    │
                  │ Scale   │    │
                  │ memory  │    │
                  └─────────┘    │
                                 │ NO
                                 ▼
                        ┌────────────────┐
                        │ Check          │
                        │ replication    │
                        └────────┬───────┘
                                 │
                            ┌────┴────┐
                            │ Lagging?│
                            ▼         │
                       ┌─────────┐    │
                       │ Scale   │    │
                       │ or fix  │    │
                       └─────────┘    │
                                      │ NO
                                      ▼
                             ┌────────────────┐
                             │ Contact IBM    │
                             │ Support        │
                             └────────────────┘

常見的反模式

避免這些導致效能問題的常見錯誤。

查詢反模式

1.遺失索引

問題:

// No index on 'email' field
db.users.find({ email: "user@example.com" })

解決方案:

// Create index
db.users.createIndex({ email: 1 })

2.低效的 regex 查詢

問題:

// Case-insensitive regex without index
db.users.find({ name: /john/i })

解決方案:

// Use text index or exact match
db.users.createIndex({ name: "text" })
db.users.find({ $text: { $search: "john" } })

3.大型 skip() 作業

問題:

// Skipping thousands of documents
db.collection.find().skip(10000).limit(10)

解決方案:

// Use range queries with indexed field
db.collection.find({ _id: { $gt: lastSeenId } }).limit(10)

4.選擇不必要的欄位

問題:

// Fetching entire documents
db.users.find({ status: "active" })

解決方案:

// Use projection
db.users.find({ status: "active" }, { name: 1, email: 1 })

5.低效的聚合管道

問題:

// $match after $lookup
db.orders.aggregate([
  { $lookup: { ... } },
  { $match: { status: "completed" } }
])

解決方案:

// $match first to reduce documents
db.orders.aggregate([
  { $match: { status: "completed" } },
  { $lookup: { ... } }
])

模式設計問題

1.無界陣列

問題:

// Array grows indefinitely
{
  userId: 123,
  activities: [/* thousands of items */]
}

解決方案:

// Use separate collection or bucketing
{
  userId: 123,
  month: "2024-01",
  activities: [/* limited items */]
}

2.過度嵌入

問題:

// Deeply nested documents
{
  user: {
    profile: {
      settings: {
        preferences: {
          // many levels deep
        }
      }
    }
  }
}

解決方案:

// Flatten or use references
{
  userId: 123,
  profileId: 456
}

3.大型文件

問題:

// Documents approaching 16MB limit
{
  data: "very large string...",
  attachments: [/* large binary data */]
}

解決方案:

// Store large data separately (GridFS or object storage)
{
  dataRef: "s3://bucket/key",
  attachments: [{ ref: "gridfs://id" }]
}

連線管理錯誤

1.未使用連線池

問題:

// Creating new connection per request
app.get('/api/users', async (req, res) => {
  const client = await MongoClient.connect(uri);
  // ...
  await client.close();
});

解決方案:

// Reuse connection pool
const client = new MongoClient(uri, { maxPoolSize: 50 });
await client.connect();

app.get('/api/users', async (req, res) => {
  const db = client.db();
  // ...
});

2.不關閉游標

問題:

// Cursor left open
const cursor = db.collection.find();
// Never closed

解決方案:

// Always close cursors
const cursor = db.collection.find();
try {
  await cursor.forEach(doc => { /* process */ });
} finally {
  await cursor.close();
}

3.連接太多

問題:

// One connection per user session
const connections = new Map();
users.forEach(user => {
  connections.set(user.id, new MongoClient(uri));
});

解決方案:

// Share connection pool across application
const client = new MongoClient(uri);
// All users share the same pool

索引陷阱

1.太多索引

問題:

// Index on every field
db.collection.createIndex({ field1: 1 })
db.collection.createIndex({ field2: 1 })
db.collection.createIndex({ field3: 1 })
// ... 20+ indexes

影響: 減慢寫入速度並增加儲存空間。

解決方案: 只保留必要的索引,並使用複合索引。

2.複合索引中索引順序錯誤

問題:

// Query: { status: "active", createdAt: { $gt: date } }
// Index: { createdAt: 1, status: 1 }  // Wrong order

解決方案:

// Correct order: equality first, range second
db.collection.createIndex({ status: 1, createdAt: 1 })

3.不使用涵蓋查詢

問題:

// Index exists but query not covered
db.users.createIndex({ email: 1 })
db.users.find({ email: "user@example.com" }, { name: 1, email: 1 })
// Still fetches documents

解決方案:

// Include all projected fields in index
db.users.createIndex({ email: 1, name: 1 })
db.users.find({ email: "user@example.com" }, { name: 1, email: 1, _id: 0 })

附錄:度量臨界值

關鍵績效指標的建議臨界值。

度量臨界值
度量 警告臨界值 嚴重臨界值 建議動作
CPU 使用率

75%

90%

縮放 CPU 核心
記憶體使用率

80%

95%

縮放記憶體分配
磁碟使用率

80%

90%

擴充磁碟空間
磁碟 IOPS 限值的 80

95% 的極限

增加磁碟大小以獲得更多 IOPS
作用中連線 限值的 80

95% 的極限

規模規劃或最佳化連線池
抄寫延遲

5 秒

30 秒

調查並視需要調整規模
快取命中率 < 95% < 90% 擴充記憶體或最佳化查詢
查詢執行時間

100ms (平均值)

1000ms (平均值)

最佳化查詢和索引
鎖定等待時間

100ms

1000ms

最佳化作業並終止長時間執行的查詢
尋頁錯失數

100/sec

1000/sec

刻度記憶
網路延遲

10ms

50ms

檢查網路設定
備份持續時間

1 小時

4 小時

考慮擴充或最佳化

監測頻率建議

監測頻率
度量種類 檢查頻率 保留期間
資源使用率 每 1 分鐘 30 天
查詢效能 每 5 分鐘 14 天
抄寫狀態 每 1 分鐘 30 天
連線統計資料 每 5 分鐘 14 天
備份狀態 每隔 1 小時 90 天
磁碟成長 每隔 1 小時 90 天

警報設定範例

CPU 警報

Condition: CPU > 80% for 10 consecutive minutes
Action: Send notification to ops team
Escalation: Page on-call if > 90% for 15 minutes

記憶體警示

Condition: Memory > 85% for 15 consecutive minutes
Action: Send notification to ops team
Escalation: Auto-scale if > 95% for 10 minutes

複製滯後警示

Condition: Lag > 10 seconds
Action: Send notification immediately
Escalation: Page on-call if > 60 seconds

磁碟空間警示

Condition: Disk > 80%
Action: Send notification to ops team
Escalation: Create incident if > 90%

最佳實務摘要

最佳作法
範疇 建議
檢索 定期檢視並移除未使用的索引
監視 設定 CPU、記憶體、磁碟和複製滯後警示
容量規劃 將磁碟使用率維持在 80% 以下,並主動進行擴充
查詢設計 在開發過程中使用解釋計劃
調整 在飽和之前主動調整規模
連線儲存區 (connection pooling) 使用連線池並避免每次要求連線
閱讀偏好 針對讀取繁重的工作負載使用副檔
書面關注 平衡耐用性與效能需求
模式設計 避免無界陣列和過度嵌入
備份規劃 安排在低流量時段
網路 IBM Cloud 工作負載使用專用端點
安全 定期輪換憑證,並使用 IP 允許列表
文件 記錄基線指標和正常模式
測試 先在非生產階段測試效能變更
支援 聯絡支援人員前先收集診斷資料

其他資源

IBM Cloud 文件

MongoDB 文件

社群資源