slowms阈值应根据业务真实响应水位设定,而非盲目采用默认100毫秒;例如报表接口可设2000毫秒,实时推荐接口则需60毫秒或更低,并配合profile级别1、合理filter及system.profile容量监控确保有效捕获慢查询。

db.setProfilingLevel 的 slowms 值怎么选
阈值不是越小越好,也不是照搬默认的 100 毫秒就万事大吉。它必须贴合你业务的真实响应水位和容忍度。比如一个报表导出接口,用户能接受 2 秒内返回,那把 slowms 设成 2000 才有意义;而一个实时推荐接口,P95 延迟压在 50 毫秒,那 slowms 就该设成 60 或更低。
常见错误是直接用默认值监控所有集合——结果 system.profile 里全是高频但轻量的查询(比如带索引的 _id 查询),反而淹没了真正拖垮服务的聚合或范围扫描。
- 先查当前负载:运行
db.currentOp({ "secs_running": { "$gt": 0.5 } })看哪些操作实际卡了半秒以上 - 再比对日志:翻
mongod.log,找频繁出现的slow query行,看它们的耗时集中在哪个区间 - 最后定值:取你关注的 P90 或 P95 耗时向上取整,作为初始
slowms
profile 级别设成 1 还是 2?
db.setProfilingLevel(1, { slowms: xxx }) 只记录慢操作,开销可控;db.setProfilingLevel(2) 记录全部操作,几乎等同于全量采样,在中高并发场景下会显著拖慢写入、甚至引发 system.profile capped 集合写满覆盖过快的问题。
除非你在做短期深度诊断(比如上线新功能后盯 10 分钟),否则永远不要长期启用 2。生产环境只用 1,配合合理的 slowms 和 filter 条件更稳妥。
- 想只抓
find和aggregate?加filter: { op: { "$in": ["query", "getmore", "aggregate"] } } - 怀疑某个集合有问题?加
filter: { ns: "mydb.mycollection" } - 避免 profile 自身写入干扰:确认
system.profile的大小足够,可用db.system.profile.stats()查 cappedSize
Atlas 环境下要不要关掉托管阈值
Atlas 默认用动态阈值(基于集群历史平均耗时自动调整),这在负载波动大的场景下容易漏掉“相对不慢但绝对超标”的查询。比如某次慢查询实际花了 180ms,但当时集群平均才 40ms,Atlas 可能就不标它为慢操作。
如果你需要稳定可比的基线(比如用于 SLO 对齐或 CI/CD 自动巡检),建议显式关闭 Atlas 托管阈值,改用固定值:
- 调用 Atlas Admin API 设置
"slowOperationThresholdMs": 100 - 或在 UI 的 Query Profiler → Settings 里手动锁定阈值(需
Project Owner权限) - 注意:M0/Flex 免费集群默认禁用托管阈值,且无法开启,这点容易被忽略
配置后怎么验证没白设
设完不验证,等于没设。最直接的验证方式是:触发一次已知的慢操作(比如一个没走索引的 find({ status: "pending" })),然后立刻查 profile 数据。
- 用
db.system.profile.find().sort({ ts: -1 }).limit(1)看最新一条是否命中 - 检查
millis字段是否 ≥ 你设的slowms,且op、ns符合预期 - 运行
db.getProfilingStatus(),确认输出中was是1,且slowms值正确 - 别只信
show profile:它默认只显示最近 5 条,且不包含完整explain信息
真正容易被忽略的是 capped 集合的生命周期——system.profile 默认只有 1MB,高负载下几分钟就刷一遍,不及时捞数据,慢查询就丢了。











