Skip to content

MongoDB - 分析查询

理解和分析查询性能对于构建可扩展且高效的应用程序至关重要。一个精心设计的索引策略可以显著提高数据库性能。在本章中,我们将探讨用于查询分析的现代工具和命令,主要关注 explain() 方法和 hint() 修饰符。

explain() 方法提供了 MongoDB 如何执行查询的详细信息。它揭示了是否使用了索引、选择了哪个执行计划,并提供了操作的统计数据。这是诊断慢查询的主要工具。

假设我们有一个 users 集合,并在 status 和 registrationDate 字段上创建了一个复合索引:

// 使用现代 mongosh shell
// 确保索引存在以供测试
db.users.createIndex({ status: 1, registrationDate: -1 });

现在,让我们分析一个查询,该查询查找今年注册的所有“活跃”用户。现代分析的关键是使用 'executionStats' 模式,它会运行查询并提供详细的执行统计信息。

db.users.find(
{
status: 'active',
registrationDate: { $gte: new Date('2024-01-01T00:00:00Z') }
}
).explain('executionStats');

现代 MongoDB 版本中 explain() 的输出虽然冗长,但信息量极大。让我们分解其关键部分:

/* 现代 explain() 输出的简化示例 */
{
"queryPlanner": {
"plannerVersion": 1,
"namespace": "testdb.users",
"winningPlan": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"keyPattern": { "status": 1, "registrationDate": -1 },
"indexName": "status_1_registrationDate_-1",
"direction": "forward",
// ... 其他索引详情
}
}
},
"executionStats": {
"executionSuccess": true,
"nReturned": 50,
"executionTimeMillis": 5,
"totalKeysExamined": 50,
"totalDocsExamined": 50,
"executionStages": {
// ... 每个阶段执行的详细分解
}
},
"serverInfo": { /* ... */ },
"ok": 1
}
  • winningPlan.stage:这显示了最终使用的计划。顶层阶段为 FETCH,且 inputStage 为 IXSCAN 是理想情况。这意味着 MongoDB 使用索引 (IXSCAN) 查找文档,然后检索 (FETCH) 完整的文档。
  • COLLSCAN:如果 COLLSCAN(集合扫描)作为获胜计划的阶段,这是一个重要的危险信号。这意味着 MongoDB 必须扫描集合中的每一个文档,表明没有找到或使用合适的索引。
  • executionStats.nReturned:与查询匹配的文档数量。
  • executionStats.totalKeysExamined:扫描的索引键数量。在非常高效的查询中,此数字应非常接近 nReturned。
  • executionStats.totalDocsExamined:扫描的完整文档数量。同样,此数字应接近 nReturned。
  • executionStats.executionTimeMillis:查询优化器和执行引擎花费的总时间。

hint() 方法强制查询优化器使用特定的索引。这对于性能测试很有用——例如,查看一个索引是否比另一个索引表现更好——但在生产环境中应极其谨慎使用。查询规划器通常更擅长选择最优索引。

// 强制使用 'status_1_registrationDate_-1' 索引
db.users.find(
{ status: 'active' }
).hint({ status: 1, registrationDate: -1 });

您可以将 hint() 与 explain() 结合使用,以查看所选索引的性能特征。

  • 覆盖查询(Covered Queries):为了获得最大性能,创建一个包含查询所需返回所有字段的索引。如果一个查询完全可以通过索引满足(无需获取文档),则称为“覆盖查询”。覆盖查询的 explain() 计划将显示一个 IXSCAN 阶段,而没有 FETCH 阶段。
  • MongoDB Compass:MongoDB 的官方 GUI 工具,提供强大的可视化“Explain Plan”功能。它对计划进行颜色编码,使得无需解析原始 JSON 就能更容易地理解性能瓶颈。
  • MongoDB Atlas 性能顾问(Performance Advisor):如果您使用 MongoDB 的云服务 Atlas,性能顾问会自动分析慢查询并建议新的索引以提高性能。这是一种主动管理数据库效率的方式。
  • 索引策略:创建复合索引时,遵循 ESR(相等、排序、范围)规则。相等匹配的字段应放在首位,其次是排序字段,最后是范围字段。