MongoDB - 分析查询
MongoDB - 分析查询性能
Section titled “MongoDB - 分析查询性能”理解和分析查询性能对于构建可扩展且高效的应用程序至关重要。一个精心设计的索引策略可以显著提高数据库性能。在本章中,我们将探讨用于查询分析的现代工具和命令,主要关注 explain() 方法和 hint() 修饰符。
现代 explain() 方法
Section titled “现代 explain() 方法”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}如何解读 Explain 计划
Section titled “如何解读 Explain 计划”winningPlan.stage:这显示了最终使用的计划。顶层阶段为FETCH,且inputStage为IXSCAN是理想情况。这意味着 MongoDB 使用索引 (IXSCAN) 查找文档,然后检索 (FETCH) 完整的文档。COLLSCAN:如果COLLSCAN(集合扫描)作为获胜计划的阶段,这是一个重要的危险信号。这意味着 MongoDB 必须扫描集合中的每一个文档,表明没有找到或使用合适的索引。executionStats.nReturned:与查询匹配的文档数量。executionStats.totalKeysExamined:扫描的索引键数量。在非常高效的查询中,此数字应非常接近nReturned。executionStats.totalDocsExamined:扫描的完整文档数量。同样,此数字应接近nReturned。executionStats.executionTimeMillis:查询优化器和执行引擎花费的总时间。
使用 hint() 强制使用索引
Section titled “使用 hint() 强制使用索引”hint() 方法强制查询优化器使用特定的索引。这对于性能测试很有用——例如,查看一个索引是否比另一个索引表现更好——但在生产环境中应极其谨慎使用。查询规划器通常更擅长选择最优索引。
// 强制使用 'status_1_registrationDate_-1' 索引db.users.find( { status: 'active' }).hint({ status: 1, registrationDate: -1 });您可以将 hint() 与 explain() 结合使用,以查看所选索引的性能特征。
现代最佳实践与工具
Section titled “现代最佳实践与工具”- 覆盖查询(Covered Queries):为了获得最大性能,创建一个包含查询所需返回所有字段的索引。如果一个查询完全可以通过索引满足(无需获取文档),则称为“覆盖查询”。覆盖查询的
explain()计划将显示一个IXSCAN阶段,而没有FETCH阶段。 - MongoDB Compass:MongoDB 的官方 GUI 工具,提供强大的可视化“Explain Plan”功能。它对计划进行颜色编码,使得无需解析原始 JSON 就能更容易地理解性能瓶颈。
- MongoDB Atlas 性能顾问(Performance Advisor):如果您使用 MongoDB 的云服务 Atlas,性能顾问会自动分析慢查询并建议新的索引以提高性能。这是一种主动管理数据库效率的方式。
- 索引策略:创建复合索引时,遵循 ESR(相等、排序、范围)规则。相等匹配的字段应放在首位,其次是排序字段,最后是范围字段。