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,排查读放大时要逐台确认状态;从节点上的慢查询同样会拖慢读路径,只看主节点容易漏掉。