MongoDB进阶
MongoDB 查询分析
## explain() >explain 操作提供了查询信息,使用索引及查询统计等。有利于我们对索引的优化。 #### explain有三种模式,分别是: - **queryPlanner(默认) :**queryPlanner模式下并不会去真正进行query语句查询,而是针对query语句进行执行计划分析并选出winning plan - **executionStats :**MongoDB运行查询优化器以选择获胜计划(winning plan),执行获胜计划直至完成,并返回描述获胜计划执行情况的统计信息。 - **allPlansExecution:** queryPlanner和executionStats都返回。相当于 explain("allPlansExecution") = explain({}) #### queryPlanner返回一些重要字段的含义 - queryPlanner.namespace:查询的哪个表 - queryPlanner.winningPlan:查询优化器针对该query所返回的最优执行计划的详细内容。 - queryPlanner.winningPlan.stage:最优计划执行的阶段,每个阶段都包含特定于该阶段的信息。例如,IXSCAN阶段将包括索引范围以及特定于索??引扫描的其他数据。如果一个阶段具有一个子阶段或多个子阶段,那么该阶段将具有inputStage或inputStages。 - queryPlanner.winningPlan.inputStage:描述子阶段的文档,该子阶段向其父级提供文档或索引键。如果父阶段只有一个孩子,则该字段存在。 - queryPlanner.winningPlan.inputStage.indexName:winning plan所选用的index,这里是根据_id来进行排序的,所以使用了_id的索引 - queryPlanner.winningPlan.inputStage.isMultiKey:是否是Multikey,此处返回是false,如果索引建立在array上,此处将是true - queryPlanner.winningPlan.inputStage.isUnique:使用的索引是否是唯一索引,这里的_id是唯一索引 - queryPlanner.winningPlan.inputStage.isSparse:是否是稀疏索引 - queryPlanner.winningPlan.inputStage.isPartial:是否是部分索引 - queryPlanner.winningPlan.inputStage.direction:此query的查询顺序,默认是forward,由于使用了sort({_id:-1})显示backward - queryPlanner.winningPlan.inputStage.indexBounds:winningplan所扫描的索引范围,由于这里使用的是sort({_id:-1}),对_id倒序排序,所以范围是[MaxKey,MinKey]。如果是正序,则是[MinKey,MaxKey] - queryPlanner.rejectedPlans:拒绝的计划详细内容,各字段含义同winningPlan #### executionStats的返回结果 - executionStats.executionSuccess:是否执行成功 - executionStats.nReturned:查询的返回条数 - executionStats.executionTimeMillis:选择查询计划和执行查询所需的总时间(以毫秒为单位) - executionStats.totalKeysExamined:索引扫描次数 - executionStats.totalDocsExamined:document扫描次数 - executionStats.executionStages:以阶段树的形式详细说明获胜计划的完成执行情况;即一个阶段可以具有一个inputStage或多个inputStages。如上说明。 - executionStats.executionStages.inputStage.keysExamined:扫描了多少次索引 - executionStats.executionStages.inputStage.docsExamined:扫描了多少次文档,一般当stage是 COLLSCAN的时候会有这个值。 - exlexecutionStats.allPlansExecution:这里展示了所有查询计划的详细。(winningPlan + rejectPlans),字段含义和winningPlan中一致 #### 15种stage 1. COLLSCAN : 扫描整个集合,这个情况是最糟糕的 2. IXSCAN : 索引扫描(index scan) 3. FETCH : 根据索引返回的结果去检索文档 4. SHARD_MERGE : 将各个分片返回数据进行merge 5. SORT : 调用了sort方法,当出现这个阶段的时候你可以看到memUsage以及memLimit这两个字段 6. SORT_KEY_GENERATOR : 在内存中进行了排序 7. LIMIT : 使用limit限制返回数 8. SKIP : 使用skip进行跳过 9. IDHACK : 针对_id进行查询 10. SHARDING_FILTER :通过mongos对分片数据进行查询 11. COUNT: 利用db.coll.explain().count()之类进行count运算, 只要调用了count方法,那么 executionStats.executionStages.stage = COUNT 12. COUNT_SCAN : count使用Index进行count时的stage返回 13. COUNTSCAN : count不使用Index进行count时的stage返回。 14. TEXT : 使用全文索引进行查询时候的stage返回 15. PROJECTION : 限定返回字段时候stage的返回 - 不希望看到的(出现以下情况,就要注意了,问题可能就出现了) COLLSCAN(全表扫描) SORT但是没有相关的索引 超大的SKIP SUBPLA在使用$or的时候没有命中索引 COUNTSCAN 执行count没有命中索引 ## hint() 虽然MongoDB查询优化器一般工作的很不错,但是也可以使用hints来强迫MongoDB使用一个指定的索引。这种方法某些情形下会提升性能。 一个有索引的collection并且执行一个多字段的查询(一些字段已经索引了)。 如下查询实例指定了使用 gender 和 user_name 索引字段来查询: ```shell db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1}) ``` 可以使用 explain() 函数来分析以上查询: ```shell db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1}).explain() ```
顶部
收展
底部
[TOC]
目录
MongoDB 查询分析
MongoDB 关系与引用
MongoDB 原子操作命令
MongoDB ObjectId
MongoDB Map Reduce
MongoDB GridFS
相关推荐
MongoDB教程
PHP操作MongoDB
MongoDB用户及安全
MongoDB优化