

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 查询运行缓慢
<a name="performance-slow-queries"></a>

## 识别-发现问题
<a name="identification-spot-problem"></a>

运行缓慢的查询是指超出业务需求预期执行时间的查询。构成慢速查询的定义因工作负载而异。您可以通过探查器日志或 Performance Insights 来识别慢速查询。

1. 如果尚未启用，请启用探查器。Profiler 日志在日志组 CloudWatch 下写入 Amazon: `/aws/docdb/<cluster-identifier>/profiler`。使用 CloudWatch Logs Insights 进行查询。

   获取 ecomerce.products 集合最慢的 10 个查询的 CloudWatch 日志分析查询@@ **示例**：

   ```
   filter ns="ecommerce.products" | sort millis desc | limit 10
   ```

1. 使用 Performance Insights 近乎实时地识别昂贵的查询。启用 Performance Insights（如果尚未启用）。

   1. 打开 AWS 控制台，导航到亚马逊 Amazon DocumentDB，然后导航到 Performance Insights，然后选择您的集群实例。

   1. 查看数据库加载 (AAS) 时间表和热门查询（按数据库负载）。展开查询摘要以查看字面子语句。

   1. 捕获需要分析的查询。
**注意**  
不是 Performance Insights 中的所有查询都可能是低效或缓慢的查询。

## 调查-收集信息
<a name="investigate-gather-information"></a>

1. 分析器提供查询执行计划和与之相关的关键指标，包括 millis、nreturn 和 PlanSummary（索引使用情况）：

   ```
   {
       "op": "query",
       "ts": 1721374275673,
       "ns": "test.perf",
       "command": {
           "find": "perf",
           "filter": {
               "threadRunCount": 0
           },
           "$db": "test",
           "lsid": {
               "id": {
                   "$binary": "oO2wEtpgQIK+y9KGByYnsw==",
                   "$type": "4"
               }
           },
           "$readPreference": {
               "mode": "secondaryPreferred"
           }
       },
       "cursorExhausted": true,
       "nreturned": 0,
       "responseLength": 0,
       "protocol": "op_query",
       "millis": 137,
       "planSummary": "IXSCAN",
       "execStats": {
           "stage": "FETCH",
           "nReturned": "0",
           "executionTimeMillisEstimate": "100.346",
           "inputStage": {
               "stage": "IXSCAN",
               "nReturned": "0",
               "executionTimeMillisEstimate": "100.342",
               "indexName": "threadRunCount_1"
           }
       },
       "client": "172.31.6.165:43154",
       "appName": "ProdAppTester14",
       "user": "adminuser"
   }
   ```

   要查找 COLLSCAN 查询：

   ```
   filter planSummary="COLLSCAN" | sort millis desc | limit 20
   ```

1. 使用 Performance Insights 实时分析查询执行趋势，例如等待、负载和资源影响（例如，每次查询的 IOPS 或 CPU）。

   由于 Performance Insights 不提供查询执行计划，因此请捕获查询并在 Amazon DocumentDB 集群上对查询运行 explain（“ExecutionStats”）：

   ```
   db.ecommerce.products.find().explain("executionStats")
   ```

1. 或者，将探查器指标与 Performance Insights 数据相关联（例如，将分析器中的高毫利查询与 Performance Insights 中的热门查询进行匹配）。

## 诊断 — 找出根本原因
<a name="diagnose-find-root-cause"></a>

在此步骤中，诊断查询计划以确定潜在的优化。使用以下流程-症状 → 可能的原因：
+ **症状：**计划摘要：“COLLSCAN”

  **原因：**索引缺失或不正确。
+ **症状：**$group/$sort 的聚合速度很慢

  **原因：**聚合管道可能处理的内存数据过多。
+ **症状：**尽管使用了索引，但 Performance Insights 显示按照 IO 等待分组的数据库负载（PlanSummary：“IXSCAN”），但延迟很高。

  **原因：** I/O 绑定查询；索引或工作集超出实例上可用的缓冲区缓存。
+ **症状：**PI 显示 CPU 等待状态，由于查询很少，AAS 过高

  **原因：** CPU-bound 查询（复杂聚合，$regex）。
+ **症状：**许多查询速度很慢，但没有一个查询显示昂贵的计划摘要

  **原因：**外部瓶颈（网络、限制、维护任务、查询量）。

## 解决-修复问题
<a name="resolve-fix-issue"></a>

实施修复时，请务必使用解释（“ExecutionStats”）进行验证，并监控 Performance Insights 数据库负载。

1. **计划摘要：“COLLSCAN”**
   + 创建目标索引。

     **示例：**对于按 {类别，价格} 筛选并按价格降序排序的频繁查询：

     ```
     db.products.createIndex({ category: 1, price: -1 })
     ```

1. **使用 $group/$sort 聚合速度很慢**
   + 尽早推送 $match 和 $project 以减少流入 $group/$sort 的文档。
   + 在管道初期限制字段的数量：

     ```
     db.products.explain("executionStats").aggregate([
       { $match: { category: "Electronics", price: { $gt: 0 } } },   // early filter
       { $project: { price: 1, category: 1 } },                     // reduce document size
       { $group: { _id: "$category", avgPrice: { $avg: "$price" } } }
     ])
     ```

1. **高延迟，而 Performance Insights 显示按 IO 等待分组的数据库负载**
   + 验证实例上 BufferCacheHitRatio 的 readiOps 是否为低或为高。增加实例内存（升级实例类，例如 r6g.large → r6g.xlarge）或使用 NVMe 实例类。
   + 减少索引占用空间。
   + 添加只读副本以卸载读取流量（如果查询容忍且最终保持一致，则使用 readPreference 设置在副本上重定向流量）。

1. **PI 显示 CPU 等待状态，由于查询很少，AAS 很高**
   + 将昂贵的 $regex 替换为索引前缀搜索或 $text 索引。
   + Batch 写入（插入）以减少写入放大。

**注意**  
在将这些更改升级到生产环境之前，请务必在较低的环境（非生产环境）中测试这些更改。