Chinaunix首页 | 论坛 | 博客
  • 博客访问: 98476
  • 博文数量: 3
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 385
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-21 12:23
个人简介

自强不息,厚德载物。

文章分类

全部博文(3)

文章存档

2016年(1)

2015年(2)

我的朋友

分类: NOSQL

2016-02-17 18:27:59

一:背景

在做客户CRM的时候有这样一个场景:在某个公司中, 某人获取自己可以查看的销售机会列表,并按照修改时间排序, 其转化为mongodb的查询为:

db.sc_info.find({did:90865,status:1, scid:{$in:[155,153,156]}}).sort({modify_time:-1})

其中did为公司IDstatus等于1表示该销售机会可以展示给任何有权限的人查看, scid表示销售机会ID, modify_tine表示最后修改时间。对于数据少量是完全没有问题, 但是如果数据量是千万级别呢?其查询根本就没法完成, 请看下面的优化过程:

二: Mongodb执行计划分析器explain

本人使用的是Moongdb3.0版本,Mongodb3.0版本的explain返回结果和以前的版本有很大的不同,介于Mongodb3.0的许多优秀特色,将3.0版本的返回分成了3个不同层面:

queryPlanner:查询计划的选择器,首先进行查询分析,最终选择一个winningPlan,是explain返回的默认层面。

executionStats:为执行统计层面,返回winningPlan的统计结果

allPlansExecution:为返回所有执行计划的统计,包括rejectedPlan

所以:我们在查询优化的时候,只需要关注queryPlanner, executionStats即可,因为queryPlanner为我们选择出了winningPlan, 而executionStats为我们统计了winningPlan的所有关键数据。

2.1 queryPlanner返回结果的意义

{

"queryPlanner" : {

"plannerVersion" : ,

"namespace" : ,

"indexFilterSet" : ,

"parsedQuery" : {

...

},

"winningPlan" : {

"stage" : ,

...

"inputStage" : {

"stage" : ,

...

"inputStage" : {

...

}

}

},

"rejectedPlans" : [

,

...

]

}



explain.queryPlanner: queryPlanner的返回

explain.queryPlanner.namespace:该值返回的是该query所查询的表

explain.queryPlanner.indexFilterSet:针对该query是否有indexfilter

explain.queryPlanner.winningPlan:查询优化器针对该query所返回的最优执行计划的详细内容。

explain.queryPlanner.winningPlan.stage:最优执行计划的stage,这里返回是FETCH,可以理解为通过返回的index位置去检索具体的文档(stage有数个模式,将在后文中进行详解)。

Explain.queryPlanner.winningPlan.inputStage:用来描述子stage,并且为其父stage提供文档和索引关键字。

explain.queryPlanner.winningPlan.stagechild stage,此处是IXSCAN,表示进行的是index scanning

explain.queryPlanner.winningPlan.keyPattern:所扫描的index内容,此处是did:1,status:1,modify_time: -1与scid : 1

explain.queryPlanner.winningPlan.indexName:winning plan所选用的index

explain.queryPlanner.winningPlan.isMultiKey是否是Multikey,此处返回是false,如果索引建立在array上,此处将是true

explain.queryPlanner.winningPlan.direction:此query的查询顺序,此处是forward,如果用了.sort({modify_time:-1})将显示backward

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

explain.queryPlanner.rejectedPlans:其他执行计划(非最优而被查询优化器reject的)的详细返回,其中具体信息与winningPlan的返回中意义相同,故不在此赘述。

2.2 executionStats返回结构的意义

"executionStats" : {

"executionSuccess" : ,

"nReturned" : ,

"executionTimeMillis" : ,

"totalKeysExamined" : ,

"totalDocsExamined" : ,

"executionStages" : {

"stage" : 

"nReturned" : ,

"executionTimeMillisEstimate" : ,

"works" : ,

"advanced" : ,

"needTime" : ,

"needYield" : ,

"isEOF" : ,

...

"inputStage" : {

"stage" : ,

...

"nReturned" : 0,

"executionTimeMillisEstimate" : ,

...

"inputStage" : {

...

}

}

},


executionStats.executionSuccess:是否执行成功

executionStats.nReturned:满足查询条件的文档个数,即查询的返回条数

executionStats.executionTimeMillis:整体执行时间

executionStats.totalKeysExamined:索引整体扫描的文档个数,和早起版本的nscanned 是一样的

executionStats.totalDocsExamined:document扫描个数, 和早期版本中的nscannedObjects 是一样的

executionStats.executionStages:整个winningPlan执行树的详细信息,一个executionStages包含一个或者多个inputStages

executionStats.executionStages.stage:这里是FETCH去扫描对于documents,后面会专门用来解释大部分查询使用到的各种stage的意思

executionStats.executionStages.nReturned:由于是FETCH,所以这里该值与executionStats.nReturned一致

executionStats.executionStages.docsExamined:与executionStats.totalDocsExamined一致executionStats.inputStage中的与上述理解方式相同

explain.executionStats.executionStages.works:被查询执行阶段所操作的“工作单元(work units)”数。

explain.executionStats.executionStages.advanced:优先返回给父stage的中间结果集中文档个数

explain.executionStats.executionStages.isEOF:查询执行是否已经到了数据流的末尾

这些值的初始值都是0Works的 值当isEOF1时要比nReturned大1, isEOF0是相同。

2.3 stage的类型的意义

mongodb的文档中列出了前4种类型,还有一些没有列出来,但是会比较常见,这里一并解释一下。

COLLSCAN :全表扫描

IXSCAN:索引扫描

FETCH:根据索引去检索指定document

SHARD_MERGE:各个分片返回数据进行merge

SORT:表明在内存中进行了排序(与前期版本的scanAndOrder:true一致)

SORT_MERGE:表明在内存中进行了排序后再合并

LIMIT:使用limit限制返回数

SKIP:使用skip进行跳过

IDHACK:针对_id进行查询

SHARDING_FILTER:通过mongos对分片数据进行查询

COUNT:利用db.coll.count()之类进行count运算

COUNTSCAN:count不使用用Index进行count时的stage返回

COUNT_SCAN:count使用了Index进行count时的stage返回

SUBPLA:未使用到索引的$or查询的stage返回

TEXT:使用全文索引进行查询时候的stage返回

附:explain查询结果解析官方文档:

阅读(6994) | 评论(0) | 转发(0) |
0

上一篇:使用宏+do...while避免C临时动态内存泄漏

下一篇:没有了

给主人留下些什么吧!~~