Docs 菜单
Docs 主页
/
MongoDB Manual
/ /

分析查询性能

在此页面上

  • 评估查询性能

cursor.explain("executionStats")db.collection.explain("executionStats") 方法提供了有关查询性能的统计信息。这些统计信息可用于衡量查询是否索引以及是如何使用该索引的。有关详细信息,请参阅 db.collection.explain()

MongoDB Compass提供“解释计划”标签页,显示有关查询性能的统计信息。 这些统计信息可用于衡量查询是否以及如何使用索引。

请考虑包含以下文档的集合 inventory

{ "_id" : 1, "item" : "f1", type: "food", quantity: 500 }
{ "_id" : 2, "item" : "f2", type: "food", quantity: 100 }
{ "_id" : 3, "item" : "p1", type: "paper", quantity: 200 }
{ "_id" : 4, "item" : "p2", type: "paper", quantity: 150 }
{ "_id" : 5, "item" : "f3", type: "food", quantity: 300 }
{ "_id" : 6, "item" : "t1", type: "toys", quantity: 500 }
{ "_id" : 7, "item" : "a1", type: "apparel", quantity: 250 }
{ "_id" : 8, "item" : "a2", type: "apparel", quantity: 400 }
{ "_id" : 9, "item" : "t2", type: "toys", quantity: 50 }
{ "_id" : 10, "item" : "f4", type: "food", quantity: 75 }

这些文档在 MongoDB Compass 中显示如下:

Compass Inventory 集合文档

以下查询检索 quantity 字段的值在 100200(含)之间的文档:

db.inventory.find( { quantity: { $gte: 100, $lte: 200 } } )

该查询返回以下文档:

{ "_id" : 2, "item" : "f2", "type" : "food", "quantity" : 100 }
{ "_id" : 3, "item" : "p1", "type" : "paper", "quantity" : 200 }
{ "_id" : 4, "item" : "p2", "type" : "paper", "quantity" : 150 }

要查看选定的查询计划,请将 cursor.explain("executionStats") 游标方法链接到 find 命令的末尾:

db.inventory.find(
{ quantity: { $gte: 100, $lte: 200 } }
).explain("executionStats")

explain() 返回以下结果:

{
"queryPlanner" : {
"plannerVersion" : 1,
...
"winningPlan" : {
"stage" : "COLLSCAN",
...
}
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 3,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 10,
"executionStages" : {
"stage" : "COLLSCAN",
...
},
...
},
...
}
  • queryPlanner.winningPlan.stage 显示 COLLSCAN,表示会进行集合扫描。

    集合扫描表明 mongod 必须对整个集合的文档进行逐份扫描才能识别结果。此项操作通常成本高昂,可能会降低查询速度。

  • executionStats.nReturned 显示 3,以指示获胜查询计划返回三个文档。

  • executionStats.totalKeysExamined显示0,表示该查询未使用索引。

  • executionStats.totalDocsExamined 显示 10,以表明 MongoDB 必须扫描 10 个文档(即集合中的所有文档),以查找三个匹配的文档。

以下查询检索 quantity 字段的值在 100200(含)之间的文档:

将以下过滤器复制到 Compass 查询栏中,然后单击 Find

{ quantity: { $gte: 100, $lte: 200 } }

该查询返回以下文档:

要查看所选的查询计划:

  1. 单击test.inventory集合的Explain Plan标签页。

  2. 单击 Explain(连接)。

MongoDB Compass 显示查询计划,如下所示:

Compass 无索引查询计划

注意

在本教程中,我们使用的数据集很小,因此,即使我们没有使用索引,Actual Query Execution Time 也会显示 0 秒。

在较大的数据集中,索引查询与非索引查询之间的查询执行时间差异会更加显著。

  • Query Performance Summary 显示查询的执行统计信息:

    • Documents Returned 显示 3,以指示获胜查询计划返回三个文档。

    • Index Keys Examined 显示 0 表明该查询未使用索引。

    • Documents Examined 显示 10 表明 MongoDB 必须扫描 10 个文档(即集合中的所有文档),以查找三个匹配的文档。

  • Query Performance Summary 下方,MongoDB Compass 显示 COLLSCAN 查询阶段,表示此查询使用了集合扫描。

    集合扫描表明 mongod 必须对整个集合的文档进行逐份扫描才能识别结果。此项操作通常成本高昂,可能会降低查询速度。

您还可以通过单击查询栏下方的 Raw JSON 以原始 JSON 格式查看解释详细信息:

Compass 无索引查询计划原始 JSON

匹配文档和已检查文档之间的数量差异可能表明,使用索引可能有助于提高查询效率。

要支持对 quantity 字段的查询,请对 quantity 字段添加索引:

db.inventory.createIndex( { quantity: 1 } )

要查看查询计划的统计信息,请使用 explain() 方法:

db.inventory.find(
{ quantity: { $gte: 100, $lte: 200 } }
).explain("executionStats")

explain() 方法返回以下结果:

{
"queryPlanner" : {
"plannerVersion" : 1,
...
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"quantity" : 1
},
...
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 3,
"executionTimeMillis" : 0,
"totalKeysExamined" : 3,
"totalDocsExamined" : 3,
"executionStages" : {
...
},
...
},
...
}
  1. 单击test.inventory集合的Indexes标签页。

  2. 单击 Create Index(连接)。

  3. Select a field name 下拉列表中选择 quantity

  4. 从类型下拉列表中选择 1 (asc)

  5. 单击 Create(连接)。

注意

将索引名称字段留空会导致 MongoDB Compass 为索引创建默认名称。

现在,您可以在 Indexes 标签页中看到新创建的索引:

Compass 显示新索引

返回到 inventory 集合的 Explain Plan 标签页,然后重新运行上一步中的查询:

{ quantity: { $gte: 100, $lte: 200 } }

MongoDB Compass 显示查询计划,如下所示:

带索引的 Compass 解释计划
  • Query Performance Summary 显示查询的执行统计信息:

    • Documents Returned 显示 3,以指示获胜查询计划返回三个文档。

    • Index Keys Examined 显示 3,以表明 MongoDB 扫描了三个索引项。检查的密钥数量与返回的文档数量相匹配,这意味着 mongod 只需要检查索引键即可返回结果。mongod 不必扫描所有文档,只需将三个匹配的文档拉取到内存中。这会大幅提升查询效率。

    • Documents Examined 显示 3 表明 MongoDB 扫描了三个文档。

    • Query Performance Summary的右侧,MongoDB Compass 显示查询使用了 quantity 索引。

  • Query Performance Summary下方, MongoDB Compass显示查询阶段FETCHIXSCANIXSCAN表示mongod在执行FETCH阶段并检索文档之前使用索引来满足查询。

您还可以通过单击查询栏下方的 Raw JSON 以原始 JSON 格式查看解释详细信息:

附带索引原始 JSON 的 Compass 查询计划

如果没有索引,此查询则会扫描整个 10 文档集合以返回 3 个匹配的文档。此查询还须扫描每个文档的全部,因而可能会将其拉取到内存中。此举会导致查询操作成本高昂且可能缓慢。

使用索引运行时,此查询已扫描 3 个索引条目和 3 个文档以返回 3 个匹配的文档,从而提升查询效率。

提示

另请参阅:

后退

CRUD 概念

在此页面上