View a markdown version of this page

查询运行缓慢 - Amazon DocumentDB

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

查询运行缓慢

识别-发现问题

运行缓慢的查询是指超出业务需求预期执行时间的查询。构成慢速查询的定义因工作负载而异。您可以通过探查器日志或 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
  2. 使用 Performance Insights 近乎实时地识别昂贵的查询。启用 Performance Insights(如果尚未启用)。

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

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

    3. 捕获需要分析的查询。

    注意

    不是 Performance Insights 中的所有查询都可能是低效或缓慢的查询。

调查-收集信息

  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
  2. 使用 Performance Insights 实时分析查询执行趋势,例如等待、负载和资源影响(例如,每次查询的 IOPS 或 CPU)。

    由于 Performance Insights 不提供查询执行计划,因此请捕获查询并在 Amazon DocumentDB 集群上对查询运行 explain(“ExecutionStats”):

    db.ecommerce.products.find().explain("executionStats")
  3. 或者,将探查器指标与 Performance Insights 数据相关联(例如,将分析器中的高毫利查询与 Performance Insights 中的热门查询进行匹配)。

诊断 — 找出根本原因

在此步骤中,诊断查询计划以确定潜在的优化。使用以下流程-症状 → 可能的原因:

  • 症状:计划摘要:“COLLSCAN”

    原因:索引缺失或不正确。

  • 症状:$group/$sort 的聚合速度很慢

    原因:聚合管道可能处理的内存数据过多。

  • 症状:尽管使用了索引,但 Performance Insights 显示按照 IO 等待分组的数据库负载(PlanSummary:“IXSCAN”),但延迟很高。

    原因: I/O 绑定查询;索引或工作集超出实例上可用的缓冲区缓存。

  • 症状:PI 显示 CPU 等待状态,由于查询很少,AAS 过高

    原因: CPU-bound 查询(复杂聚合,$regex)。

  • 症状:许多查询速度很慢,但没有一个查询显示昂贵的计划摘要

    原因:外部瓶颈(网络、限制、维护任务、查询量)。

解决-修复问题

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

  1. 计划摘要:“COLLSCAN”

    • 创建目标索引。

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

      db.products.createIndex({ category: 1, price: -1 })
  2. 使用 $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" } } } ])
  3. 高延迟,而 Performance Insights 显示按 IO 等待分组的数据库负载

    • 验证实例上 BufferCacheHitRatio 的 readiOps 是否为低或为高。增加实例内存(升级实例类,例如 r6g.large → r6g.xlarge)或使用 NVMe 实例类。

    • 减少索引占用空间。

    • 添加只读副本以卸载读取流量(如果查询容忍且最终保持一致,则使用 readPreference 设置在副本上重定向流量)。

  4. PI 显示 CPU 等待状态,由于查询很少,AAS 很高

    • 将昂贵的 $regex 替换为索引前缀搜索或 $text 索引。

    • Batch 写入(插入)以减少写入放大。

注意

在将这些更改升级到生产环境之前,请务必在较低的环境(非生产环境)中测试这些更改。