首页/数据/NoSQL 速查/慢查询剖析器 profiling
MongoDB99 条

慢查询剖析器 profiling

profiler 把慢操作写入 system.profile 集合:setProfilingLevel(1, {slowms}) 只记录超阈值操作,level 2 记录全部(慎用)。

NoSQL 速查数据更新于 2026-10-13

profiler 是什么

profiler 把数据库上执行的操作记录下来写入 system.profile 集合,用来回答「这条慢查询到底做了什么」。setProfilingLevel(1, { slowms }) 只记录超过阈值的操作,level 2 记录全部操作(开销与磁盘增长都很明显,只适合短时间排查)。开启后可以按耗时、执行计划摘要(COLLSCAN 还是 IXSCAN)、扫描文档数与返回条数的比例来判断瓶颈,是数据库侧最直接的性能证据来源。

基本信息

记录慢操作db.setProfilingLevel(1, { slowms: 200 })
记录全部db.setProfilingLevel(2)
关闭db.setProfilingLevel(0)
查看状态db.getProfilingStatus()
查看记录db.system.profile.find().sort({ ts: -1 }).limit(5)
权限需要数据库上的 dbAdmin 权限

典型使用场景

  • 定位慢查询:找出超过阈值且反复出现的操作,确定优化优先级
  • 验证索引效果:对比加索引前后扫描文档数与耗时的变化
  • 排查全表扫描:看执行计划摘要是 COLLSCAN 还是 IXSCAN
  • 分析写放大:观察大批量更新与删除带来的长时间操作
  • 故障复盘:事故后按时间窗口回捞当时的操作记录

开启与查读

开启与查读
db.setProfilingLevel(1, { slowms: 200 })   // 只记录超过 200 毫秒的操作
db.getProfilingStatus()                    // 确认当前级别与阈值

db.system.profile.find({ millis: { $gt: 200 } })    // 慢操作明细
  .sort({ ts: -1 }).limit(10).pretty()

db.system.profile.find({ planSummary: "COLLSCAN" }).count()   // 统计全表扫描次数

db.setProfilingLevel(0)                    // 排查结束立即关闭

记录字段读法

字段含义读法
millis操作耗时(毫秒)明显超过业务预期就要查索引
planSummary执行计划摘要COLLSCAN 表示全表扫描
docsExamined扫描的文档数远大于返回条数说明索引没用好
keysExamined扫描的索引键数与返回条数差距大要调整索引
ts记录时间按时间窗口定位故障时段
op操作类型区分查询、更新、删除带来的不同压力
记录里带执行计划摘要,看 docsExamined 与返回条数的比例往往一眼就能判断是「索引没命中」还是「查询本身设计有问题」。
level 2 会记录每一个操作,写入量、CPU 与磁盘增长都很可观,只能在短时间排查窗口内开启,用完立刻关闭。
副本集的每个成员都有各自的 profiler,排查读放大时要逐台确认状态;从节点上的慢查询同样会拖慢读路径,只看主节点容易漏掉。

易错点

  • level 2 全量记录带来明显开销与磁盘增长,只在短时间排查时开启
  • system.profile 本身是普通集合,长期开启会把它撑得很大,需要主动清理
  • 只看 millis 不看 docsExamined,容易把「扫描量大」误判成「查询写法慢」
  • 分片集群要逐个分片确认 profiler 状态,只在 mongos 上开启收集不到全部慢操作

数据来源与参考

  • MongoDB Manual: Database Profiler
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌