MongoDB Compass 的性能分析器本质上是一个可视化前端,它读取数据库中 system.profile 集合的数据。该集合只有在开启数据库分析器后才会记录操作,因此如果直接在 Compass 中打开性能标签却看不到任何数据,通常不是界面问题,而是当前数据库的分析级别仍然是 0。理解这一点是使用好性能分析器的前提。

性能分析器的数据来源与开启方式
MongoDB 数据库分析器有三个级别。级别 0 表示关闭,不会记录任何操作;级别 1 只记录执行时间超过 slowms 阈值的慢操作,这是日常排查中最常用的配置;级别 2 会记录所有读写操作,虽然信息最完整,但会给数据库带来明显开销,通常只在短时间复现问题时临时开启。在 Compass 中查看性能面板前,需要先在目标数据库上确认分析级别不为 0。
如果使用 mongosh 连接数据库,可以用下面命令快速查看和设置分析器。将级别设为 1 并指定 100 毫秒阈值,可以在数据量和信息量之间取得平衡。
// 查看当前分析级别
db.getProfilingStatus()
// 开启慢查询记录,阈值100毫秒
db.setProfilingLevel(1, { slowms: 100 })
// 关闭分析器
db.setProfilingLevel(0)
设置完成后,Compass 的性能标签页就能读取到 system.profile 集合中的记录。打开 Compass,选择对应的数据库,再点击 Performance 标签,可以看到按时间排序的操作列表。右上角可以切换数据库和刷新频率。需要注意的是 system.profile 集合有固定大小,旧数据会被新数据覆盖,因此如果慢查询发生时间较早,可能需要重现一次操作才能看到记录。
读懂性能面板中的关键指标
性能面板中的每一条记录对应一次数据库操作,字段与 system.profile 文档基本一致。比较重要的有 op 表示操作类型,ns 表示命名空间,millis 表示执行耗时,planSummary 表示查询计划摘要,docsExamined 表示扫描的文档数,nreturned 表示返回的文档数。理解这几个指标之间的关系,是判断慢查询原因的关键。
举例来说,假设订单集合 orders 中有两百万条文档,应用程序执行了下面这个查询。它在 Compass 中显示耗时 1200 毫秒,planSummary 为 COLLSCAN,docsExamined 为 2000000,而 nreturned 只有 20。
db.orders.find({
customerId: 12345,
status: "PAID"
}).sort({ createdTime: -1 }).limit(20)
这里的 COLLSCAN 表示全集合扫描,也就是没有使用索引。扫描两百万文档只返回 20 条,这个比例说明查询非常低效。除了扫描数量,还可以关注锁等待时间。在 Compass 中把鼠标悬停到某条记录上,可以展开查看更详细的执行统计,包括索引使用、排序方式以及是否存在内存排序。如果发现 SORT 阶段使用了内存排序且文档较多,也需要考虑调整索引字段顺序。
用执行计划和索引建议修复慢查询
继续上面的订单查询,问题主要出在 customerId 和 status 两个过滤条件没有合适的索引,同时按 createdTime 倒序排序。如果只给 customerId 建立单字段索引,虽然能缩小扫描范围,但排序阶段仍可能产生额外开销。对于这种条件组合,复合索引通常更有效。
在 Compass 中可以直接查看该操作的执行计划。选择一条慢记录,切换到 Explain 或 Index 相关视图,Compass 会根据查询模式给出索引建议。也可以手动在 mongosh 中创建索引。下面这个复合索引包含等值字段、状态字段和排序字段,比较适合上述查询。
db.orders.createIndex({
customerId: 1,
status: 1,
createdTime: -1
})
创建索引后重新执行同一查询,planSummary 会从 COLLSCAN 变为 IXSCAN,docsExamined 可能从两百万下降到几十或几百,millis 也会大幅降低。需要提醒的是 Compass 的索引建议适合作为参考,并不总是最优。例如 status 字段如果只有 PAID 和 UNPAID 两种值,选择性并不高,放在复合索引的第二个位置通常可以接受,但如果某个字段区分度很低,建索引反而会浪费写性能。实际项目中还要结合数据分布、写入频率和查询占比综合判断。
Compass图形界面与命令行协同排查
Compass 的优势在于可视化、操作直观,适合快速定位某段时间内的慢操作,不必记住 system.profile 的字段结构。但在生产环境或自动化排查场景中,mongosh 命令行仍然更灵活。例如需要按耗时、命名空间或操作类型过滤记录时,可以直接查询 system.profile 集合,并将结果导出或写入日志系统。
// 查询最近超过200毫秒的查询操作
db.system.profile.find({
millis: { $gt: 200 },
op: "query"
}).sort({ ts: -1 }).limit(10)
上面这段命令可以快速列出最近的慢查询。结合 Compass 的执行计划视图,就能形成一套排查流程:先用命令行或 Compass 找到慢操作,再在 Compass 里展开细节,判断是扫描过多还是排序过大,最后用查询模式设计索引。两类工具并不是替代关系,而是互补关系。熟悉这种协同方式后,遇到 MongoDB 性能问题时,可以更快定位到具体字段和索引方向,减少盲目调整。
MongoDB Compass性能分析器慢查询优化修改时间:2026-09-17 09:32:02