本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
查询运行缓慢
识别-发现问题
运行缓慢的查询是指超出业务需求预期执行时间的查询。构成慢速查询的定义因工作负载而异。您可以通过探查器日志或 Performance Insights 来识别慢速查询。
-
如果尚未启用,请启用探查器。Profiler 日志在日志组 CloudWatch 下写入 Amazon:
/aws/docdb/<cluster-identifier>/profiler。使用 CloudWatch Logs Insights 进行查询。获取 ecomerce.products 集合最慢的 10 个查询的 CloudWatch 日志分析查询@@ 示例:
filter ns="ecommerce.products" | sort millis desc | limit 10 -
使用 Performance Insights 近乎实时地识别昂贵的查询。启用 Performance Insights(如果尚未启用)。
-
打开 AWS 控制台,导航到亚马逊 Amazon DocumentDB,然后导航到 Performance Insights,然后选择您的集群实例。
-
查看数据库加载 (AAS) 时间表和热门查询(按数据库负载)。展开查询摘要以查看字面子语句。
-
捕获需要分析的查询。
注意
不是 Performance Insights 中的所有查询都可能是低效或缓慢的查询。
-
调查-收集信息
-
分析器提供查询执行计划和与之相关的关键指标,包括 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 -
使用 Performance Insights 实时分析查询执行趋势,例如等待、负载和资源影响(例如,每次查询的 IOPS 或 CPU)。
由于 Performance Insights 不提供查询执行计划,因此请捕获查询并在 Amazon DocumentDB 集群上对查询运行 explain(“ExecutionStats”):
db.ecommerce.products.find().explain("executionStats") -
或者,将探查器指标与 Performance Insights 数据相关联(例如,将分析器中的高毫利查询与 Performance Insights 中的热门查询进行匹配)。
诊断 — 找出根本原因
在此步骤中,诊断查询计划以确定潜在的优化。使用以下流程-症状 → 可能的原因:
-
症状:计划摘要:“COLLSCAN”
原因:索引缺失或不正确。
-
症状:$group/$sort 的聚合速度很慢
原因:聚合管道可能处理的内存数据过多。
-
症状:尽管使用了索引,但 Performance Insights 显示按照 IO 等待分组的数据库负载(PlanSummary:“IXSCAN”),但延迟很高。
原因: I/O 绑定查询;索引或工作集超出实例上可用的缓冲区缓存。
-
症状:PI 显示 CPU 等待状态,由于查询很少,AAS 过高
原因: CPU-bound 查询(复杂聚合,$regex)。
-
症状:许多查询速度很慢,但没有一个查询显示昂贵的计划摘要
原因:外部瓶颈(网络、限制、维护任务、查询量)。
解决-修复问题
实施修复时,请务必使用解释(“ExecutionStats”)进行验证,并监控 Performance Insights 数据库负载。
-
计划摘要:“COLLSCAN”
-
创建目标索引。
示例:对于按 {类别,价格} 筛选并按价格降序排序的频繁查询:
db.products.createIndex({ category: 1, price: -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" } } } ])
-
-
高延迟,而 Performance Insights 显示按 IO 等待分组的数据库负载
-
验证实例上 BufferCacheHitRatio 的 readiOps 是否为低或为高。增加实例内存(升级实例类,例如 r6g.large → r6g.xlarge)或使用 NVMe 实例类。
-
减少索引占用空间。
-
添加只读副本以卸载读取流量(如果查询容忍且最终保持一致,则使用 readPreference 设置在副本上重定向流量)。
-
-
PI 显示 CPU 等待状态,由于查询很少,AAS 很高
-
将昂贵的 $regex 替换为索引前缀搜索或 $text 索引。
-
Batch 写入(插入)以减少写入放大。
-
注意
在将这些更改升级到生产环境之前,请务必在较低的环境(非生产环境)中测试这些更改。