MongoDB 分析查询性能

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: cursor.explain("executionStats")和 db.collection.explain("executionStats") 方法提供关于查询性能的相关信息。这些信息可用于衡量查询是否使用了索引以及如何使用索引。db.collection.explain() 还提供有关其他操作的执行信息。例如 db.collection.update()。 有关详情信息,请参见 db.collection.explain() 。评价查询性能考虑采用以下的 inventory 集合文档:

cursor.explain("executionStats")和 db.collection.explain("executionStats") 方法提供关于查询性能的相关信息。这些信息可用于衡量查询是否使用了索引以及如何使用索引。

db.collection.explain() 还提供有关其他操作的执行信息。例如 db.collection.update()。 有关详情信息,请参见 db.collection.explain() 。

评价查询性能
考虑采用以下的 inventory 集合文档:

db.inventory.insert([

{ "_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 }

]);
不使用索引查询
以下查询返回 quantity 值在 100 到 200 之间(含)的文档:

db.inventory.find( { quantity: { $gte: 100, $lte: 200 } } )
将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表示查询匹配到并返回3个文档。
executionStats.totalKeysExamined 显示0表示这个查询没有使用索引。
executionStats.totalDocsExamined 显示10表示MongoDB扫描了10个文档,从中查询匹配到3个文档。
匹配文档的数量与检查文档的数量之间的差异可能意味着,查询可以使用索引提高的查询效率。

基于索引查询
为了查询支持 quantity 字段,在 quantity 字段上新增索引:

db.inventory.createIndex( { quantity: 1 } )
使用 explain("executionStats") 方法,显示查询计划信息:

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" : {
        ...
     },
     ...

},
...
}
queryPlanner.winningPlan.inputStage.stage 显示 IXSCAN 表示使用了索引。
executionStats.nReturned 显示3表示查询匹配到并返回3个文档。
executionStats.totalKeysExamined 显示3表示MongoDB 扫描了3个索引数据。 检查的键数与返回的文档数相匹配,这意味着mongod只需检查索引键即可返回结果。mongod不必扫描所有文档,只有三个匹配的文档被拉入内存。 这个查询结果是非常高效的。
executionStats.totalDocsExamined 显示3表示MongoDB扫描了3个文档。
没有使用索引时查询将扫描整个集合中的10个文档返回匹配到的3个文档。查询时会将它们拉入内存并扫描卖QQ平台每个文档的整体。这个结果非常耗性能并且潜在的会导致查询变慢。

当使用索引运行时,查询扫描3个索引条目然后3个文档中返回匹配到的3个文档,这个查询结果非常高效。

比较索引的性能
查询时不止一个索引时手动的比较索引性能,可以使用 hint() 方法再结合 explain() 方法。

考虑下面的查询:

db.inventory.find( {
quantity: {

  $gte: 100, $lte: 300

},
type: "food"
} )
查询结果如下:

{ "_id" : 2, "item" : "f2", "type" : "food", "quantity" : 100 }
{ "_id" : 5, "item" : "f3", "type" : "food", "quantity" : 300 }
为了支持这个查询,添加复合索引。复合索引中字段的顺序很重要。

例如,添加如下的2个复合索引。第一个索引先使用 quantity ,再使用 type 字段创建索引。第二个索引先使用 type ,再使用 quantity 字段创建索引。

db.inventory.createIndex( { quantity: 1, type: 1 } )
db.inventory.createIndex( { type: 1, quantity: 1 } )
查询使用第一个索引来评估性能:

db.inventory.find(
{ quantity: { $gte: 100, $lte: 300 }, type: "food" }
).hint({ quantity: 1, type: 1 }).explain("executionStats")
这个 explain() 方法返回如下输出信息:

{
"queryPlanner" : {

  ...
  "winningPlan" : {
     "stage" : "FETCH",
     "inputStage" : {
        "stage" : "IXSCAN",
        "keyPattern" : {
           "quantity" : 1,
           "type" : 1
        },
        ...
        }
     }
  },
  "rejectedPlans" : [ ]

},
"executionStats" : {

  "executionSuccess" : true,
  "nReturned" : 2,
  "executionTimeMillis" : 0,
  "totalKeysExamined" : 6,
  "totalDocsExamined" : 2,
  "executionStages" : {
  ...
  }

},
...
}
MongoDB 扫描了6条索引键 (executionStats.totalKeysExamined) 并返回了2条匹配到的文档(executionStats.nReturned)。

查询使用第二个索引来评估性能:

db.inventory.find(
{ quantity: { $gte: 100, $lte: 300 }, type: "food" }
).hint({ type: 1, quantity: 1 }).explain("executionStats")
这个 explain() 方法返回如下输出信息:

{
"queryPlanner" : {

  ...
  "winningPlan" : {
     "stage" : "FETCH",
     "inputStage" : {
        "stage" : "IXSCAN",
        "keyPattern" : {
           "type" : 1,
           "quantity" : 1
        },
        ...
     }
  },
  "rejectedPlans" : [ ]

},
"executionStats" : {

  "executionSuccess" : true,
  "nReturned" : 2,
  "executionTimeMillis" : 0,
  "totalKeysExamined" : 2,
  "totalDocsExamined" : 2,
  "executionStages" : {
     ...
  }

},
...
}
MongoDB 扫描了2条索引键 (executionStats.totalKeysExamined) 并返回了2条匹配到的文档(executionStats.nReturned)。

这个查询例子中,复合索引 {type:1,quantity:1} 比复合索引 {quantity:1,type:1} 更高效。

目录
相关文章
|
NoSQL MongoDB 数据库
MongoDB日志浅析
MongoDB 日志
7035 0
|
NoSQL 索引
MongoDB查询优化:从 10s 到 10ms
本文是我前同事付秋雷最近遇到到一个关于MongoDB执行计划选择的问题,非常有意思,在探索源码之后,他将整个问题搞明白并整理分享出来。付秋雷(他的博客)曾是Tair(阿里内部用得非常官方的KV存储系统)的核心开发,目前就职于蘑菇街。
|
12月前
|
存储 NoSQL MongoDB
掌握MongoDB索引优化策略:提升查询效率的关键
在数据库性能调优中,索引是提升查询效率的利器。本文将带你深入了解MongoDB索引的内部工作原理,探讨索引对查询性能的影响,并通过实际案例指导如何针对不同的查询模式建立有效的索引。不仅将涵盖单一字段索引,还会探讨复合索引的使用,以及如何通过分析查询模式和执行计划来优化索引,最终实现查询性能的最大化。
|
6月前
|
安全 算法 数据建模
HTTPS证书类型和品牌一览
HTTPS证书(SSL证书)是保障网站数据传输安全与身份可信认证的重要工具,适用于电商、企业官网等各类平台。证书主要分为DV(域名验证)、OV(企业验证)、EV(扩展验证)三种安全级别,以及单域名、通配符、多域名等不同覆盖类型。品牌方面,既有高性价比的国产锐安信、CFCA,也有国际知名的Sectigo、Digicert。
|
安全 Java
IntelliJ Idea 常用快捷键列表
这是一份IntelliJ IDEA常用快捷键列表,涵盖了代码编辑、文件操作、重构、查找及调试等多种开发场景。例如,使用Ctrl+Shift+Enter完成语句,Ctrl+E打开最近的文件,Ctrl+Shift+E查看最近更改的文件,以及Alt+Q预览当前方法声明等,极大地提升了开发效率。
359 0
|
12月前
|
存储 NoSQL MongoDB
MongoDB 查询分析
10月更文挑战第21天
103 1
|
运维 NoSQL Linux
MongoDB详解(六)——MongoDB主从同步配置
MongoDB详解(六)——MongoDB主从同步配置
892 5
|
算法 Java 测试技术
【TarsosDSP】TarsosDSP 简介 ( TarsosDSP 功能 | 相关链接 | 源码和相关资源收集 | TarsosDSP 示例应用 | TarsosDSP 源码路径解析 )(二)
【TarsosDSP】TarsosDSP 简介 ( TarsosDSP 功能 | 相关链接 | 源码和相关资源收集 | TarsosDSP 示例应用 | TarsosDSP 源码路径解析 )(二)
922 0
【TarsosDSP】TarsosDSP 简介 ( TarsosDSP 功能 | 相关链接 | 源码和相关资源收集 | TarsosDSP 示例应用 | TarsosDSP 源码路径解析 )(二)
|
3天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
2天前
|
云安全 人工智能 自然语言处理
阿里云x硅基流动:AI安全护栏助力构建可信模型生态
阿里云AI安全护栏:大模型的“智能过滤系统”。