1. 索引管理

创建索引并在后台运行

db.COLLECTION_NAME.createIndex({"字段":排序方式}, {background: true});

获取针对某个集合的索引

db.COLLECTION_NAME.getIndexes()

索引的大小

db.COLLECTION_NAME.totalIndexSize()

索引的重建

db.COLLECTION_NAME.reIndex()

索引的删除

db.COLLECTION_NAME.dropIndex("INDEX-NAME") 
db.COLLECTION_NAME.dropIndexes()
注意: _id 对应的索引是删除不了的

2. explain 分析

测试可以使用js循环插入100万条数据 不使用索引字段 查询查看执行计划 ,然后给某个字段建立索引,使用索引字段作为查询条件 再查看执行计划进行分析

explain()也接收不同的参数,通过设置不同参数我们可以查看更详细的查询计划。

  • queryPlanner:是默认参数,具体执行计划信息参考下面的表格。
  • executionStats:会返回执行计划的一些统计信息(有些版本中和allPlansExecution等同)。
  • allPlansExecution:用来获取所有执行计划,结果参数基本与上文相同。
2.1 queryPlanner 默认参数

参数

含义

plannerVersion

查询计划版本

namespace

要查询的集合(该值返回的是该query所查询的表)数据库.集合

indexFilterSet

针对该query是否有indexFilter

parsedQuery

查询条件

winningPlan

被选中的执行计划

winningPlan.stage

被选中执行计划的stage(查询方式),常见的有:COLLSCAN/全表 扫描:(应该知道就是CollectionScan,就是所谓的“集合扫描”, 和mysql中table scan/heap scan类似,这个就是所谓的性能最烂 最无奈的由来)、IXSCAN/索引扫描:(是IndexScan,这就说明 我们已经命中索引了)、FETCH/根据索引去检索文档、 SHARD_MERGE/合并分片结果、IDHACK/针对_id进行查询等

winningPlan.inputStage

用来描述子stage,并且为其父stage提供文档和索引关键字。

winningPlan.stage的child stage

如果此处是IXSCAN,表示进行的是index scanning。

winningPlan.keyPattern

所扫描的index内容

winningPlan.indexName

winning plan所选用的index。

winningPlan.isMultiKey

是否是Multikey,此处返回是false,如果索引建立在array上,此 处将是true。

winningPlan.direction

此query的查询顺序,此处是forward,如果用了.sort({字段:-1}) 将显示backward。

filter

过滤条件

winningPlan.indexBounds

winningplan所扫描的索引范围,如果没有制定范围就是[MaxKey, MinKey],这主要是直接定位到mongodb的chunck中去查找数 据,加快数据读取。

rejectedPlans

被拒绝的执行计划的详细返回,其中具体信息与winningPlan的返 回中意义相同,故不在此赘述)

serverInfo

MongoDB服务器信息

2.2 executionStats参数

参数

含义

executionSuccess

是否执行成功

nReturned

返回的文档数

executionTimeMillis

执行耗时

totalKeysExamined

索引扫描次数

totalDocsExamined

文档扫描次数

executionStages

这个分类下描述执行的状态

stage

扫描方式,具体可选值与上文的相同

nReturned

查询结果数量

executionTimeMillisEstimate

检索document获得数据的时间

inputStage.executionTimeMillisEstimate

该查询扫描文档 index所用时间

works

工作单元数,一个查询会分解成小的工作单元

advanced

优先返回的结果数

docsExamined

文档检查数目,与totalDocsExamined一致。检查了总共的document 个数,而从返回上面的nReturned数量

2.3 executionStats返回逐层分析

第一层

executionTimeMillis最为直观explain返回值是executionTimeMillis值,指的是这条语句的执 行时间,这个值当然是希望越少越好。其中有3个executionTimeMillis,分别是:

  • executionStats.executionTimeMillis 该query的整体查询时间。
  • executionStats.executionStages.executionTimeMillisEstimate 该查询检索document获得数据的时 间。
  • executionStats.executionStages.inputStage.executionTimeMillisEstimate 该查询扫描文档 index 所用时间。

第二层:index与document扫描数与查询返回条目数 这个主要讨论3个返回项

  • nReturned: 查询返回的条目
  • totalKeysExamined:索引扫描条目
  • totalDocsExamined:文档扫描 条目

这些都是直观地影响到executionTimeMillis,我们需要扫描的越少速度越快。 对于一个查询, 我们最理想的状态是:nReturned=totalKeysExamined=totalDocsExamined

第三层:stage的类型影响到了totalKeysExamined和totalDocsExamined,类型列举如下:

  1. COLLSCAN:全表扫描
  2. IXSCAN:索引扫描
  3. FETCH:根据索引去检索指定document
  4. SHARD_MERGE:将各个分片返回数据进行merge
  5. SORT:表明在内存中进行了排序
  6. LIMIT:使用limit限制返回数
  7. SKIP:使用skip进行跳过
  8. IDHACK:针对_id进行查询
  9. SHARDING_FILTER:通过mongos对分片数据进行查询
  10. COUNT:利用db.coll.explain().count()之类进行count运算
  11. TEXT:使用全文索引进行查询时候的stage返回
  12. PROJECTION:限定返回字段时候stage的返回

对于普通查询,我希望看到stage的组合(查询的时候尽可能用上索引):

  1. Fetch+IDHACK
  2. Fetch+IXSCAN
  3. Limit+(Fetch+IXSCAN)
  4. PROJECTION+IXSCAN
  5. SHARDING_FITER+IXSCAN

不希望看到包含如下的stage:

  1. COLLSCAN(全表扫描)
  2. SORT(使用sort但是无index)
  3. COUNT 不使用index进行count)

3. 慢查询分析

  1. 开启内置的查询分析器,记录读写操作效率 db.setProfilingLevel(n,m),n的取值可选0,1,2
    0表示不记录
    1表示记录慢速操作,如果值为1,m必须赋值单位为ms,用于定义慢速查询时间的阈值
    2表示记录所有的读写操作
  2. 查询监控结果 db.system.profile.find().sort({millis:-1}).limit(3)
  3. 分析慢速查询 应用程序设计不合理、不正确的数据模型、硬件配置问题,缺少索引等
  4. 解读explain结果 确定是否缺少索引