码迷,mamicode.com
首页 > 数据库 > 详细

mongodb之慢查询分析

时间:2015-10-22 14:21:00      阅读:912      评论:0      收藏:0      [点我收藏+]

标签:mongodb 慢查询 explain分析

  1  摘要

  在MySQL中,慢查询日志是经常作为我们优化查询的依据,那在MongoDB中是否有类似的功能呢?答案是肯定的,那就是开启Profiling功能。该工具在运行的实例上收集有关MongoDB的写操作,游标,数据库命令等,可以在数据库级别开启该工具,也可以在实例级别开启。该工具会把收集到的所有都写入到system.profile集合中,该集合是一个capped collection。更多的信息见:http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/

 2  使用说明

2.1  Profiling级别说明

0:关闭,不收集任何数据。
1:收集慢查询数据,默认是100毫秒。
2:收集所有数据

2.2  开启Profiling和设置

1:通过mongo shell:

#查看状态:级别和时间
PRIMARY> db.getProfilingStatus()
{ "was" : 1, "slowms" : 200 }
#查看级别
PRIMARY> db.getProfilingLevel()
1
#设置级别
PRIMARY> db.setProfilingLevel(2)
{ "was" : 1, "slowms" : 100, "ok" : 1 }
#设置级别和时间
PRIMARY> db.setProfilingLevel(1,200)
{ "was" : 2, "slowms" : 100, "ok" : 1 }

注意:

  1  以上要操作要是在test集合下面的话,只对该集合里的操作有效,要是需要对整个实例有效,则需要在所有的集合下设置或则在开启的时候开启参数

  2 每次设置之后返回给你的结果是修改之前的状态(包括级别、时间参数)。


2:不通过mongo shell:

在mongoDB启动的时候

mongod --profile=1  --slowms=200

或则在配置文件里添加2行:

profile = 1
slowms = 200

3:关闭Profiling

# 关闭
PRIMARY> db.setProfilingLevel(0)
{ "was" : 1, "slowms" : 200, "ok" : 1 }

4:修改“慢查询日志”的大小

#关闭Profiling
PRIMARY> db.setProfilingLevel(0)
{ "was" : 0, "slowms" : 200, "ok" : 1 }
#删除system.profile集合
PRIMARY> db.system.profile.drop()
true
#创建一个新的system.profile集合 --- 4M
PRIMARY> db.createCollection( "system.profile", { capped: true, size:4000000 } )
{ "ok" : 1 }
#重新开启Profiling
PRIMARY> db.setProfilingLevel(1)
{ "was" : 0, "slowms" : 200, "ok" : 1 }

注意:要改变Secondary的system.profile的大小,你必须停止Secondary,运行它作为一个独立的mongodb,然后再执行上述步骤。完成后,重新启动加入副本集。


3   慢查询(system.profile)说明

通过下面的例子说明,更多信息见:http://docs.mongodb.org/manual/reference /database-profiler/

3.1:参数含义

{
	"op" : "query",  #操作类型,有insert、query、update、remove、getmore、command   
	"ns" : "onroad.route_model", #操作的集合
	"query" : {
		"$query" : {
			"user_id" : 314436841,
			"data_time" : {
				"$gte" : 1436198400
			}
		},
		"$orderby" : {
			"data_time" : 1
		}
	},
	"ntoskip" : 0, #指定跳过skip()方法 的文档的数量。
	"nscanned" : 2, #为了执行该操作,MongoDB在 index 中浏览的文档数。 一般来说,如果 nscanned 值高于 nreturned 的值,说明数据库为了找到目标文档扫描了很多文档。这时可以考虑创建索引来提高效率。
	"nscannedObjects" : 1,  #为了执行该操作,MongoDB在 collection中浏览的文档数。
	"keyUpdates" : 0, #索引更新的数量,改变一个索引键带有一个小的性能开销,因为数据库必须删除旧的key,并插入一个新的key到B-树索引
	"numYield" : 1,  #该操作为了使其他操作完成而放弃的次数。通常来说,当他们需要访问还没有完全读入内存中的数据时,操作将放弃。这使得在MongoDB为了放弃操作进行数据读取的同时,还有数据在内存中的其他操作可以完成
	"lockStats" : {  #锁信息,R:全局读锁;W:全局写锁;r:特定数据库的读锁;w:特定数据库的写锁
		"timeLockedMicros" : {  #该操作获取一个级锁花费的时间。对于请求多个锁的操作,比如对 local 数据库锁来更新 oplog ,该值比该操作的总长要长(即 millis )
			"r" : NumberLong(1089485),
			"w" : NumberLong(0)
		},
		"timeAcquiringMicros" : {  #该操作等待获取一个级锁花费的时间。
			"r" : NumberLong(102),
			"w" : NumberLong(2)
		}
	},
	"nreturned" : 1,  // 返回的文档数量
	"responseLength" : 1669, // 返回字节长度,如果这个数字很大,考虑值返回所需字段
	"millis" : 544, #消耗的时间(毫秒)
	"execStats" : {  #一个文档,其中包含执行 查询 的操作,对于其他操作,这个值是一个空文件, system.profile.execStats 显示了就像树一样的统计结构,每个节点提供了在执行阶段的查询操作情况。
		"type" : "LIMIT", ##使用limit限制返回数  
		"works" : 2,
		"yields" : 1,
		"unyields" : 1,
		"invalidates" : 0,
		"advanced" : 1,
		"needTime" : 0,
		"needFetch" : 0,
		"isEOF" : 1,  #是否为文件结束符
		"children" : [
			{
				"type" : "FETCH",  #根据索引去检索指定document
				"works" : 1,
				"yields" : 1,
				"unyields" : 1,
				"invalidates" : 0,
				"advanced" : 1,
				"needTime" : 0,
				"needFetch" : 0,
				"isEOF" : 0,
				"alreadyHasObj" : 0,
				"forcedFetches" : 0,
				"matchTested" : 0,
				"children" : [
					{
						"type" : "IXSCAN", #扫描索引键
						"works" : 1,
						"yields" : 1,
						"unyields" : 1,
						"invalidates" : 0,
						"advanced" : 1,
						"needTime" : 0,
						"needFetch" : 0,
						"isEOF" : 0,
						"keyPattern" : "{ user_id: 1.0, data_time: -1.0 }",
						"boundsVerbose" : "field #0[‘user_id‘]: [314436841, 314436841], field #1[‘data_time‘]: [1436198400, inf.0]",
						"isMultiKey" : 0,
						"yieldMovedCursor" : 0,
						"dupsTested" : 0,
						"dupsDropped" : 0,
						"seenInvalidated" : 0,
						"matchTested" : 0,
						"keysExamined" : 2,
						"children" : [ ]
					}
				]
			}
		]
	},
	"ts" : ISODate("2015-10-15T07:41:03.061Z"), #该命令在何时执行
	"client" : "10.10.86.171", #链接ip或则主机
	"allUsers" : [
		{
			"user" : "martin_v8",
			"db" : "onroad"
		}
	],
	"user" : "martin_v8@onroad"
}














本文出自 “一个奋斗的小运维” 博客,请务必保留此出处http://yucanghai.blog.51cto.com/5260262/1705195

mongodb之慢查询分析

标签:mongodb 慢查询 explain分析

原文地址:http://yucanghai.blog.51cto.com/5260262/1705195

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!