

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 長時間執行的查詢
<a name="anti-pattern-long-running-queries"></a>

## 概觀
<a name="long-queries-overview"></a>

長時間執行的查詢可能會層疊到整個叢集的效能問題。這些查詢可能會干擾 Amazon DocumentDB 的多版本並行控制 (MVCC) 垃圾收集程序，導致舊版本的文件累積，並降低叢集的效能。Amazon DocumentDB 實作 2 小時伺服器端逾時做為安全機制，以限制失控查詢無限期地耗用資源。

**什麼是長時間執行的查詢：**
+ 長時間執行的查詢 （通常 > 30 分鐘）
+ 開啟處於作用中狀態數小時的游標 （如果游標處於作用中狀態，則 2 小時逾時不適用）

## 對叢集的影響
<a name="long-queries-impact"></a>

**長時間執行的查詢可能會干擾垃圾回收程序**
+ **舊版本累積**：垃圾收集器無法回收舊文件版本
+ **集合和索引膨脹**：集合和索引項目會隨著時間累積、膨脹增加，並可能導致更多的儲存成本。
+ **CPU 和記憶體壓力**：由於舊文件版本、索引項目和交易 IDs 數量增加的處理效率不佳，CPU 和記憶體壓力會增加。

長時間執行的查詢 → 封鎖 GC → 儲存成長 → CPU 和記憶體壓力 → 更長的查詢

## 監控和偵測
<a name="long-queries-monitoring"></a>

**1。若要尋找長時間執行的查詢，請使用 currentOp 命令。**

```
// To find a query running for more than 30 mins
db.adminCommand({
    aggregate: 1,
    pipeline: [
        {$currentOp: {}},
        {$match: 
            {$or: 
                [{secs_running: {$gt: 1800}},
                 {WaitState: {$exists: true}}]}}],
    cursor: {}
});
```

**2. 尋找作用中超過 30 分鐘的游標**

```
// To find cursor which is running more than 30 mins
db.adminCommand({
    "currentOp": true,
    "active": true,
    "$all": true
}).inprog.filter(function(op) {
    return op.desc == "Cursor" && 
           op.secs_running > 1800 && 
           op.active == true;
}).sort((a, b) => b.microsecs_running - a.microsecs_running)
```

**3. 透過 CloudWatch 監控垃圾收集器進度**

`LongestRunningGCProcess`— 最長作用中垃圾回收程序的持續時間，以秒為單位。每分鐘更新一次，並僅追蹤作用中的操作，不包括在一分鐘時段內完成的程序。

`AvailableMVCCIds` - 顯示達到零之前可用的剩餘寫入操作數量的計數器。當此計數器達到零時，您的叢集會進入唯讀模式IDs直到 ID 回收和回收為止。計數器會隨著每次寫入操作而減少，並隨著垃圾回收回收舊的 MVCC IDs 而增加。

**注意**  
較低的 MVCC IDs 和延長的垃圾收集期間並非僅歸因於長時間執行的查詢。資源限制執行個體上的寫入密集型工作負載也可能導致 MVCC ID 可用性降低和垃圾收集週期延長。

## 修復策略
<a name="long-queries-remediation"></a>
+ 在應用程式中實作查詢逾時
+ 請勿讓游標存活更長的時間
+ 最佳化查詢以獲得更好的效能。
+ 偏好批次處理寫入操作