效能與資源使用率 - Amazon DocumentDB

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

效能與資源使用率

本節提供 Amazon DocumentDB 部署中常見診斷問題的問題和解決方案。這些範例會提供使用 mongo 殼層,而且範圍限定在個別執行個體的示範。若要尋找執行個體端點 , 請參閱了解 Amazon DocumentDB 端點

如何確定通過 Mongo API 在我的集合上執行的插入,更新和刪除操作的數量?

若要檢視對特定集合執行的插入、更新和刪除作業數目,請在該集合上執行下列命令:

db.collection.stats()

此命令的輸出描述了其opCounters字段下的以下內容:

  • numDocsIns-插入此集合中的文檔數量。這包括使用insertinsertMany指令插入的文件,以及 upsert 插入的文件。

  • numDocsUpd-此集合中的文檔更新數量。這包括使用updatefindAndModify指令更新的文件。

  • numDocsDel-從此集合中刪除的文檔數量。這包括使用deleteOnedeleteManyremovefindAndModify指令刪除的文件。

  • LaStreSet-這些計數器上次重設的時間。啟動/停止叢集或擴展/縮減執行個體時,會重設此命令提供的統計資料。

從運行db.collection.stats()的一個例子輸出如下所示。

{ "ns" : "db.test", "count" : ..., "size" : ..., "avgObjSize" : ..., "storageSize" : ..., "capped" : false, "nindexes" : ..., "totalIndexSize" : ..., "indexSizes" : { "_id_" : ..., "x_1" : ... }, "collScans" : ..., "idxScans" : ..., "opCounter" : { "numDocsIns" : ..., "numDocsUpd" : ..., "numDocsDel" : ... }, "cacheStats" : { "collBlksHit" : ..., "collBlksRead" : .., "collHitRatio" : ..., "idxBlksHit" : ..., "idxBlksRead" : ..., "idxHitRatio" : ... }, "lastReset" : "2022-09-02 19:41:40.471473+00", "ok" : 1, "operationTime" : Timestamp(1662159707, 1) }

通過 Mongo API 查看集合特定計數器插入,更新和刪除操作時,應使用此統計命令。另一種檢視集合特定作業計數器的方法是啟用 DML 稽核。您可以在中檢視一分鐘時間間隔內對所有集合的插入、更新和刪除作業數目使用 監控 Amazon DocumentDB CloudWatch

如何分析快取效能?

分析快取效能可以深入瞭解資料擷取的效率和系統效能,並以從磁碟讀取的資料量與快取為基礎。我們提供有關緩存命中數(從緩存中讀取的數據)和緩存未命中(未在緩存中找到並從磁盤讀取數據)的緩存統計信息,以便深入了解緩存性能。特定集合的快取統計資料可以透過在該集合上執行下列命令來找到:

db.collection.stats()

此命令輸出中cacheStats欄位中的值會提供集合的快取統計資料,以及在集合上建立之索引的總快取統計資料。這些統計數據列舉如下:

  • collBlksHit-執行此集合作業期間,從快取讀取的區塊數目。

  • collBlksRead-在此集合作業期間,從磁碟讀取的區塊數目 (快取遺漏)。

  • collHitRatio-此集合 (100 * [collBlksHit / (collBlksHit + collBlksRead)]) 的快取命中率。

  • idxBlksHit-針對此集合上建立的任何索引,從快取讀取的區塊數目。

  • idxBlksRead-針對此集合上建立的任何索引,從磁碟讀取的區塊數目 (快取遺漏)。

  • idxHitRatio-在此集合 () 上建立之索引的快取命中100 * [idxBlksHit / (idxBlksHit + idxBlksRead)]率。

  • lastReset-上次重設這些統計資料的時間。啟動/停止叢集或向上/縮減執行個體時,會重設提供的統計資料。db.collection.stats()

您也可以使用指indexStats令找到每個索引的idxBlksHitidxBlksRead欄位劃分。索引特定的快取統計資料可以透過執行下列命令找到:

db.collection.aggregate([{$indexStats:{}}]).pretty()

對於每個索引,您可以在cacheStats欄位下找到下列快取統計資料:

  • blksHit-從快取中讀取此索引的區塊數目。

  • blksRead-從磁碟讀取此索引的區塊數目。

  • blksHitRatio-快取命中率四捨五入至四位小數,計算方式為100 * [blksHit / (blksHit + blksRead)]

如何尋找並終止長時間執行或封鎖的查詢?

使用者查詢執行緩慢的原因,可能是查詢計畫不佳,或因為資源爭用而遭封鎖。

若要尋找因查詢計畫不佳而造成長時間執行查詢的效率變慢,或因為資源爭用而遭封鎖的查詢,請先使用 currentOp 命令。您可以篩選命令,以利減縮要終止的相關查詢清單。您必須具備與長時間執行查詢相關聯的 opid,才能夠終止查詢。

以下查詢會使用 currentOp 命令來列出所有遭到封鎖或執行超過 10 秒的查詢。

db.adminCommand({ aggregate: 1, pipeline: [ {$currentOp: {}}, {$match: {$or: [ {secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}, {$project: {_id:0, opid: 1, secs_running: 1}}], cursor: {} });

接著,您就可以縮減查詢,尋找並終止執行超過 10 秒的查詢 opid

尋找和終止執行超過 10 秒的查詢
  1. 尋找查詢的 opid

    db.adminCommand({ aggregate: 1, pipeline: [ {$currentOp: {}}, {$match: {$or: [{secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}], cursor: {} });

    此操作的輸出將會如下所示 (JSON 格式)。

    { "waitedMS" : NumberLong(0), "cursor" : { "firstBatch" : [ { "opid" : 24646, "secs_running" : 12 } ], "id" : NumberLong(0), "ns" : "admin.$cmd" }, "ok" : 1 }
  2. 使用 killOp 操作終止查詢。

    db.adminCommand({killOp: 1, op: 24646});

如何查看查詢計劃並優化查詢?

查詢的執行速度如果緩慢,可能是由於查詢執行需要完整掃描集合來選擇相關的文件。有時,建立適當的索引能夠使查詢的執行速度更快。若要偵測這種情況並決定建立索引的欄位,請使用 explain 命令。

注意

Amazon DocumentDB 會在使用分散式容錯、自我修復儲存系統的專用資料庫引擎上模擬 MongoDB 3.6 API。因此,Amazon DocumentDB 和 MongoDB 之間的查詢計劃和輸出explain()可能會有所不同。想要控制其查詢計劃的客戶可以使用 $hint 運算子強制選取偏好的索引。

請在 explain 命令下執行您要改善的查詢,如下所示。

db.runCommand({explain: {<query document>}})

下面是範例操作。

db.runCommand({explain:{ aggregate: "sample-document", pipeline: [{$match: {x: {$eq: 1}}}], cursor: {batchSize: 1}} });

此操作的輸出將會如下所示 (JSON 格式)。

{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "db.test", "winningPlan" : { "stage" : "COLLSCAN" } }, "serverInfo" : { "host" : "...", "port" : ..., "version" : "..." }, "ok" : 1 }

上述輸出表示 $match 階段需要掃描完整的集合,並確認每個文件中的欄位 "x" 皆等於 1。如果集合中有多個文件,則集合掃描速度 (和必然的整體查詢效能) 將非常緩慢。因此,explain 命令輸出中的 "COLLSCAN" 表示可以透過建立適當的索引來提高查詢效能。

在此範例中,查詢會檢查所有文件中的欄位 "x" 是否等於 1。因此建立欄位 "x" 的索引,便可讓查詢避免完整集合掃描,並且使用索引加快相關文件傳回。

在欄位 "x" 上建立索引後,explain 輸出如下所示。

{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "db.test", "winningPlan" : { "stage" : "IXSCAN", "indexName" : "x_1", "direction" : "forward" } }, "serverInfo" : { "host" : "...", "port" : ..., "version" : "..." }, "ok" : 1 }

在欄位 "x" 上建立索引將使 $match 階段能夠使用索引掃描,以減少必須進行評估之述詞 "x = 1" 的文件數量。

對於小型集合,如果效能提升可忽略不計,Amazon DocumentDB 查詢處理器可以選擇不使用索引。

如何在彈性集群中查看查詢計劃?

若要檢查彈性叢集中的查詢計劃,請使用explain命令。以下是針對分片集合的 find 查詢explain操作的示例操作:

db.runCommand( { explain: { find: "cities", filter: {"name": "Seoul"}} } )
注意

Amazon DocumentDB 模擬 MongoDB 在專門建立的數據庫引擎上。因此,Amazon DocumentDB 和 MongoDB 之間的查詢計劃和輸出explain()可能會有所不同。您可以使用$hint運算子來強制選取偏好索引來控制查詢計劃。

此操作的輸出可能如下所示(JSON 格式):

{ "queryPlanner" : { "elasticPlannerVersion" : 1, "winningPlan" : { "stage" : "SINGLE_SHARD", "shards" : [ { "plannerVersion" : 1, "namespace" : "population.cities", "winningPlan" : { "stage" : "SHARD_MERGE", "shards" : [ { "shardName" : "f2cf5cfd-fe9c-40ca-b4e5-298ca0d11111", "plannerVersion" : 1, "namespace" : "population.cities", "winningPlan" : { "stage" : "PARTITION_MERGE", "inputStages" : [ { "stage" : "COLLSCAN", "partitionCount" : 21 } ] } }, { "shardName" : "8f3f80e2-f96c-446e-8e9d-aab8c7f22222", "plannerVersion" : 1, "namespace" : "population.cities", "winningPlan" : { "stage" : "PARTITION_MERGE", "inputStages" : [ { "stage" : "COLLSCAN", "partitionCount" : 21 } ] } }, { "shardName" : "32c5a06f-1b2b-4af1-8849-d7c4a033333", "plannerVersion" : 1, "namespace" : "population.cities", "winningPlan" : { "stage" : "PARTITION_MERGE", "inputStages" : [ { "stage" : "COLLSCAN", "partitionCount" : 22 } ] } } ] }, "shardName" : "32c5a06f-1b2b-4af1-8849-d7c4a0f3fb58" } ] } }, "serverInfo" : { "host" : "example-4788267630.us-east-1.docdb-elastic.amazonaws.com:27017", "version" : "5.0.0" }, "ok" : 1, "operationTime" : Timestamp(1695097923, 1) }

上述輸出會顯示三分片叢集上find查詢的查詢計畫。每個分片都有多個數據分區,可以具有不同的輸入階段。在此範例中,在每個碎片內的「PARTITION_MERGE」階段合併結果之前,會在所有磁碟分割上執行「COLLSCAN」(集合掃描)。然後,碎片中的結果將在「SHARD_MERGE」階段合併在一起,然後再發送回客戶端。

如何列出執行個體上所有正在執行的操作?

身為使用者或主要使用者,您通常會想要列出執行個體上執行的所有目前作業,以便進行診斷和疑難排解。(如需有關管理使用者的詳細資訊,請參閱 管理 Amazon DocumentDB 用戶。)

使用命mongo令介面,您可以使用下列查詢列出 Amazon DocumentDB 執行個體上所有執行中的操作。

db.adminCommand({currentOp: 1, $all: 1});

此查詢會傳回一份完整清單,內含所有使用者查詢和執行個體目前正在操作的內部系統任務。

此操作的輸出將會如下所示 (JSON 格式)。

{ "inprog" : [ { "desc" : "INTERNAL" }, { "desc" : "TTLMonitor", "active" : false }, { "client" : ..., "desc" : "Conn", "active" : true, "killPending" : false, "opid" : 195, "ns" : "admin.$cmd", "command" : { "currentOp" : 1, "$all" : 1 }, "op" : "command", "$db" : "admin", "secs_running" : 0, "microsecs_running" : NumberLong(68), "clientMetaData" : { "application" : { "name" : "MongoDB Shell" }, "driver" : { ... }, "os" : { ... } } }, { "desc": "GARBAGE_COLLECTION", "garbageCollection": { "databaseName": "testdb", "collectionName": "testCollectionA" }, "secs_running": 3, "microsecs_running": NumberLong(3123456) }, { "desc": "GARBAGE_COLLECTION", "garbageCollection": { "databaseName": "testdb", "collectionName": "testCollectionB" }, "secs_running": 4, "microsecs_running": NumberLong(4123456) } ], "ok" : 1 }

以下是 "desc" 欄位的有效值:

  • INTERNAL— 內部系統任務,如光標清理或過時的用戶清理任務。

  • TTLMonitor— 存活時間 (TTL) 監視執行緒。其執行狀態會反映在 "active" 欄位。

  • GARBAGE_COLLECTION— 內部記憶體回收器執行緒。

  • CONN— 使用者查詢。

  • CURSOR— 該操作是空閒的光標,等待用戶調用「getMore」命令以獲取下一批結果。在此狀態下,游標正在消耗記憶體,但不會消耗任何計算。

前述輸出也會列出系統中執行的所有使用者查詢。每個使用者查詢會在資料庫和集合的內容中執行,這兩者的聯集稱為命名空間"ns" 欄位會提供每個使用者查詢的命名空間。

有時您需要列出在特定命名空間中執行的所有使用者查詢。因此,之前的輸出必須經過 "ns" 欄位篩選。下面是為達到篩選輸出的範例查詢。查詢會列出資料庫 "db" 和集合 "test" (即 "db.test" 命名空間) 中目前正在執行的所有使用者查詢。

db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {allUsers: true, idleConnections: true}}, {$match: {ns: {$eq: "db.test"}}}], cursor: {} });

身為系統的主要使用者,您可以查看所有使用者的查詢,以及所有內部系統作業。所有其他使用者都只能查看其各自查詢。

如果查詢和內部系統任務的總數超過預設批次處理游標大小,則 mongo 殼層將自動產生迭代器物件 'it' 以查看其餘結果。請持續執行命令 'it',直到所有結果都已用盡。

我如何知道查詢何時正在進行?

使用者查詢執行緩慢的原因,可能是查詢計畫不佳,或因為資源爭用而遭封鎖。偵錯此類查詢需要進行多個步驟,而其有時需要多次執行相同的步驟。

偵錯的第一步是列出長時間執行或封鎖的所有查詢。下列查詢列出執行超過 10 秒或等待資源的所有使用者查詢。

db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {}}, {$match: {$or: [{secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}, {$project: {_id:0, opid: 1, secs_running: 1, WaitState: 1, blockedOn: 1, command: 1}}], cursor: {} });

請定期重複上述查詢,判斷查詢清單是否變更,並找出長時間執行的查詢或遭封鎖的查詢。

如果您查詢的輸出文件中包含 WaitState 欄位,則表示資源爭用是造成查詢執行速度緩慢或遭封鎖的原因。資源爭用的可能成因是 IO、內部系統任務或其他使用者查詢。

此操作的輸出將會如下所示 (JSON 格式)。

{ "waitedMS" : NumberLong(0), "cursor" : { "firstBatch" : [ { "opid" : 201, "command" : { "aggregate" : ... }, "secs_running" : 208, "WaitState" : "IO" } ], "id" : NumberLong(0), "ns" : "admin.$cmd" }, "ok" : 1 }

如果同時在相同執行個體上執行的不同集合中有多個查詢,或執行個體大小對執行查詢的資料集而言太小,則 I/O 可能成為瓶頸。如果查詢是唯讀查詢,則您可以在不同複本上分隔每個集合的查詢,有效緩解這個情況。若是跨不同集合的並行更新,或執行個體的大小對資料集而言太小,則您可以向上擴展執行個體來進行緩解。

如果資源爭用是由其他使用者查詢所引起,則輸出文件中的 "blockedOn" 欄位將包含影響此查詢之查詢的 "opid"。使用 "opid" 追蹤所有查詢的 "WaitState""blockedOn" 欄位鏈結,以在鏈結的前端尋找查詢。

如果鏈結前端的任務為內部任務,則唯一的緩解措施是終止查詢,並在一段時間後重新執行該查詢。

在以下的範例輸出中,其尋找查詢在另一個任務擁有的集合鎖上遭到封鎖。

{ "inprog" : [ { "client" : "...", "desc" : "Conn", "active" : true, "killPending" : false, "opid" : 75, "ns" : "...", "command" : { "find" : "...", "filter" : { } }, "op" : "query", "$db" : "test", "secs_running" : 9, "microsecs_running" : NumberLong(9449440), "threadId" : 24773, "clientMetaData" : { "application" : { "name" : "MongoDB Shell" }, "driver" : { ... }, "os" : { ... } }, "WaitState" : "CollectionLock", "blockedOn" : "INTERNAL" }, { "desc" : "INTERNAL" }, { "client" : "...", ... "command" : { "currentOp" : 1 }, ... } ], "ok" : 1 }

如果 "WaitState" 具有值 "Latch""SystemLock""BufferLock""BackgroundActivity""Other",則資源爭用來源為內部系統任務。如果情況持續很長一段時間,則唯一的緩解措施是終止該查詢,並在一段時間後重新執行該查詢。

如何確定系統突然運行緩慢的原因?

下面列出系統變慢的一些常見原因:

  • 並行查詢之間的資源爭用過多

  • 作用中並行查詢的數量會隨著時間增加

  • 內部系統任務,例如 "GARBAGE_COLLECTION"

若要隨著時間監控系統使用量,請定期執行下列 "currentOp" 查詢,並將結果輸出到外部存放區。該查詢會計算系統中每個命名空間的查詢和操作數量。接著,您就可以分析系統使用量結果來了解系統負載,並採取適當行動。

db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {allUsers: true, idleConnections: true}}, {$group: {_id: {desc: "$desc", ns: "$ns", WaitState: "$WaitState"}, count: {$sum: 1}}}], cursor: {} });

此查詢會傳回每個命名空間中執行之所有查詢和所有內部系統任務的彙總,以及每個命名空間專屬的等待狀態數量。

此操作的輸出將會如下所示 (JSON 格式)。

{ "waitedMS" : NumberLong(0), "cursor" : { "firstBatch" : [ { "_id" : { "desc" : "Conn", "ns" : "db.test", "WaitState" : "CollectionLock" }, "count" : 2 }, { "_id" : { "desc" : "Conn", "ns" : "admin.$cmd" }, "count" : 1 }, { "_id" : { "desc" : "TTLMonitor" }, "count" : 1 } ], "id" : NumberLong(0), "ns" : "admin.$cmd" }, "ok" : 1 }

在前述輸出中,命名空間 "db.test" 中有 2 個使用者查詢在集合鎖定上遭到封鎖:其中 1 個查詢位於命名空間 "admin.$cmd" 中,另一個位於內部 "TTLMonitor" 任務中。

如果輸出指出許多查詢處於封鎖等待狀態,請參閱如何尋找並終止長時間執行或封鎖的查詢?

如何判斷一或多個叢集執行個體上 CPU 使用率過高的原因?

下列各節可協助您識別高執行個體 CPU 使用率的原因。結果可能因工作負載而有差異。

根據造成高執行個體 CPU 使用率的原因,執行下列一項或多項動作可能有所幫助。

  • 如果主要執行個體顯示高 CPU 使用率,但複本執行個體未顯示同樣情況,則請考慮透過用戶端讀取偏好設定 (例如 secondaryPreferred),將讀取流量分配至所有複本。如需詳細資訊,請參閱 連接到 Amazon DocumentDB 作為複本集

    使用複本進行讀取時,因為主要執行個體可以處理更多寫入流量,進而有效提升叢集資源的使用效能。來自複本的讀取最終會保持一致。

  • 如果寫入工作負載的結果是造成高 CPU 使用率,則將叢集執行個體的大小變更為較大的執行個體類型,將會增加可用於服務工作負載的 CPU 核心數量。如需詳細資訊,請參閱 執行個體執行個體類別規格

  • 如果所有叢集執行個體都呈現高 CPU 使用率,且工作負載使用複本進行讀取,則新增更多複本到叢集時,可供讀取流量使用的資源將會增加。如需詳細資訊,請參閱 將 Amazon DocumentDB 執行個體新增至叢集

如何確定實例上的打開游標?

連線到 Amazon DocumentDB 執行個體時,您可以使用命令列出該執db.runCommand("listCursors")行個體上開啟的游標。在指定的 Amazon DocumentDB 執行個體上,任何指定時間最多可開啟 4,560 個作用中游標,視執行個體類型而定。我們通常建議關閉不再使用的游標,因為游標會使用執行個體上的資源,且有數目上限的限制。請參閱Amazon DocumentDB Quotas 和限制以取得特定限制。

db.runCommand("listCursors")

如何確定當前的 Amazon DocumentDB 引擎版本?

若要判斷您目前的 Amazon DocumentDB 引擎版本,請執行下列命令。

db.runCommand({getEngineVersion: 1})

此操作的輸出將會如下所示 (JSON 格式)。

{ "engineVersion" : "2.x.x", "ok" : 1 }
注意

Amazon DocumentDB 3.6 的引擎版本是 1.x.x 和 Amazon DocumentDB 4.0 的引擎版本是 2.x.x。

如何分析索引使用情況並識別未使用的索引?

若要識別指定集合的索引,請執行下列命令:

db.collection.getIndexes()

若要分析對集合執行作業期間使用的索引數量,可以使用collStatsindexStats指令。若要檢視使用索引 (索引掃描) 執行的掃描總數與不使用索引執行的掃描次數 (收集掃描) 的比較,請執行下列命令:

db.collection.stats()

此命令的輸出包括下列值:

  • idxScans-使用索引對此集合執行的掃描次數。

  • collScans-對此集合執行的掃描次數,但不使用索引。這些掃描將涉及一次查看集合中的文檔。

  • lastReset-這些計數器上次重置的時間 啟動/停止叢集或擴展/縮減執行個體時,會重設此命令提供的統計資料。

在以下命令的輸出中可以找到每個索引使用量的細分。最佳作法是定期識別和移除未使用的索引,以改善效能並降低成本,因為它可以消除用於維護索引的不必要運算、儲存和 I/O。

db.collection.aggregate([{$indexStats:{}}]).pretty()

此命令的輸出會為集合上建立的每個索引提供下列值:

  • ops-使用索引的作業數目。如果您的工作負載已執行足夠長的時間,而且您確信您的工作負載處於穩定狀態,ops 的零值表示完全不使用索引。

  • numDocsRead-使用此索引作業期間讀取的文件數目。

  • since-自 Amazon DocumentDB 開始收集索引使用狀況統計資料以來的時間,這通常是自上次資料庫重新啟動或維護動作以來的值。

  • size-此索引的大小 (以位元組為單位)。

下列範例是執行上述命令的範例輸出:

{ "name" : "_id_", "key" : { "_id" : 1 }, "host" : "example-host.com:12345", "size" : NumberLong(...), "accesses" : { "ops" : NumberLong(...), "docsRead" : NumberLong(...), "since" : ISODate("...") }, "cacheStats" : { "blksRead" : NumberLong(...), "blksHit" : NumberLong(...), "hitRatio" : ... } } { "name" : "x_1", "key" : { "x" : 1 }, "host" : "example-host.com:12345", "size" : NumberLong(...), "accesses" : { "ops" : NumberLong(...), "docsRead" : NumberLong(...), "since" : ISODate("...") }, "cacheStats" : { "blksRead" : NumberLong(...), "blksHit" : NumberLong(...), "hitRatio" : ... } }

若要判斷集合的整體索引大小,請執行下列命令:

db.collection.stats()

若要刪除未使用的索引,請執行下列命令:

db.collection.dropIndex("indexName")

如何識別遺失的索引?

您可以使用 Amazon DocumentDB 效能分析工具來記錄慢速查詢。在慢速查詢日誌中重複出現查詢,可能表示需要額外的索引來改善該查詢的效能。

您可以找出實用索引的機會,方法是尋找有一或多個階段執行至少一個 COLLSCAN 個階段的長時間執行查詢,這表示它們查詢階段必須讀取集合中的每個文件,以提供對查詢的回應。

下列範例顯示在大型集合上執行的計程車乘車查詢。

db.rides.count({"fare.totalAmount":{$gt:10.0}}))

為了執行這個範例,查詢必須執行集合掃描 (即讀取集合中的每個文件),因為該 fare.totalAmount 欄位上沒有索引。此查詢的 Amazon DocumentDB 效能分析工具的輸出如下所示:

{ ... "cursorExhausted": true, "nreturned": 0, "responseLength": 0, "protocol": "op_query", "millis": 300679, "planSummary": "COLLSCAN", "execStats": { "stage": "COLLSCAN", "nReturned": "0", "executionTimeMillisEstimate": "300678.042" }, "client": "172.31.5.63:53878", "appName": "MongoDB Shell", "user": "example" }

為了加快這個例子中的查詢,您可在 fare.totalAmount 建立一個索引,如下圖所示。

db.rides.createIndex( {"fare.totalAmount": 1}, {background: true} )
注意

在前景中建立的索引 (也就是說,如果建立索引時未提供 {background:true} 選項) 會採用獨佔寫入鎖定,這樣可以防止應用程式在索引建立完成之前將資料寫入集合。在生產叢集上建立索引時,請注意這項潛在影響。建立索引時,建議設定 {background:true}

一般而言,您會希望在具有高基數 (例如,大量唯一值) 的欄位上建立索引。在低基數的欄位上建立索引可能會導致有大型索引未使用。建立查詢計劃時,Amazon DocumentDB 查詢最佳化工具會考量索引集合的整體大小和選擇性。有時候,您會看到查詢處理器選擇一個 COLLSCAN,即使索引已存在。當查詢處理器預估,相較於掃描整個集合,利用索引並不會產生效能優勢時,就會發生這種情況。如果您想強制查詢處理器利用一個特定索引,您可以使用 hint() 運算子,如下圖所示。

db.collection.find().hint("indexName")

有用的查詢摘要

下列查詢對於在 Amazon DocumentDB 中監控效能和資源使用率非常有用。

  • 您可以使用下列命令來檢視特定集合的統計資料,包括作業計數器、快取統計資料、存取統計資料和大小統計資料:

    db.collection.stats()
  • 您可以使用下列命令來檢視集合上建立之每個索引的統計資料,包括索引的大小、索引特定快取統計資料,以及索引使用狀況統計資料:

    db.collection.aggregate([{$indexStats:{}}]).pretty()
  • 使用以下查詢來列出所有活動。

    db.adminCommand({currentOp: 1, $all: 1});
  • 下面程式碼會列出所有長時間執行或遭封鎖的查詢。

    db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {}}, {$match: {$or: [{secs_running: {$gt: 10}}, {WaitState: {$exists: true}}]}}, {$project: {_id:0, opid: 1, secs_running: 1, WaitState: 1, blockedOn: 1, command: 1}}], cursor: {} });
  • 下列程式碼會終止查詢。

    db.adminCommand({killOp: 1, op: <opid of running or blocked query>});
  • 使用下列程式碼來取得系統狀態的彙總檢視。

    db.adminCommand({aggregate: 1, pipeline: [{$currentOp: {allUsers: true, idleConnections: true}}, {$group: {_id: {desc: "$desc", ns: "$ns", WaitState: "$WaitState"}, count: {$sum: 1}}}], cursor: {} });