MongoDB性能分析和优化1(explain演示)

MongoDB 查询分析可以确保我们建议的索引是否有效,是查询语句性能分析的重要工具。
MongoDB 查询分析常用函数有:explain() 和 hint()。
先给小伙伴们进行explain演示,hint演示请看下一篇博客。

1. explain演示
在数据量和吞吐量越发庞大的今天,优化查询速度是提高系统性能的一个关键点,而获取这类相关信息的重要诊断工具之一就是explain(),引用《MongoDb权威指南》书中的解释:
通过查看一个查询(find)的explain()输出信息,可以知道查询使用了哪个索引,以及是如何使用的。
最常见的输出有两种类型:使用索引的查询和没有使用索引的查询
(1)构建数据
为了方便演示,我需要先创建一个没有索引的表,如下图:
在这里插入图片描述
(2)explain使用
1.创建索引

db.collection.createIndex(keys, options)

keys由文档字段和索引类型组成。如{“name”:1}
key 表示字段 value 1,-1 1表示升序,-1降序
示例:db.getCollection('u_friends').createIndex({"status":1})
2. 查看索引

db.collection.getIndexes()

示例:db.getCollection('u_friends').getIndexes()
在这里插入图片描述
3.删除索引

db.collection.dropIndex(index) 

删除指定的索引。

db.collection.dropIndexes() 

删除除了_id 以外的所有索引。

示例: db.getCollection('u_friends').dropIndex("status_1")
4. 创建复合索引

  db.collection.createIndex(keys, options,keys1,options1)

示例:db.getCollection('u_friends').createIndex({"status":1,"offlineNoPushMsg":1})
5. 其他操作
给字段name 创建索引并命名为myindex
示例:db.userdatas.createIndex({"name":1},{"name":"myindex"})

当mongodb 集合里面的数据过大时 创建索引很耗时,可以在放在后台运行。
示例: db.userdatas.createIndex({"name":1},{"name":"myindex","background":true})

给age 字段创建唯一索引

db.userdatas.createIndex({"age":-1},{"name":"ageIndex","unique":true,"sparse":true})

总结
1:创建索引时,1表示按升序存储,-1表示按降序存储。
2:可以创建复合索引,如果想用到复合索引,必须在查询条件中包含复合索引中的前N个索引列
3: 如果查询条件中的键值顺序和复合索引中的创建顺序不一致的话,
MongoDB可以智能的帮助我们调整该顺序,以便使复合索引可以为查询所用。
4: 可以为内嵌文档创建索引,其规则和普通文档创建索引是一样的。
5: 一次查询中只能使用一个索引,$or特殊,可以在每个分支条件上使用一个索引。
6: where,where,exists不能使用索引,还有一些低效率的操作符,比如:ne,ne,not,$nin等。
7: 设计多个字段的索引时,应该尽量将用于精确匹配的字段放在索引的前面。

1.现实开发中,常用的是executionStats模式,主要分析这种模式。
explain()必须放在语句最后面
示例:db.getCollection('u_friends').find({'status':{"$eq":2}}).explain()
在这里插入图片描述
返回结果包含两大块信息,一个是queryPlanner,即查询计划,还有一个是serverInfo,即MongoDB服务的一些信息。那么这里涉及到的参数比较多,我们来一一看一下:
在这里插入图片描述
executionStats会返回最佳执行计划的一些统计信息,如下:
在这里插入图片描述
在这里插入图片描述
allPlansExecution用来获取所有执行计划,结果参数基本与上文相同

(3) 无索引查询

在这里插入图片描述
从上图中,我们看到了三个圈圈,这些都是我们在find中非常重要的信息,具体信息解释如下:
<1>COLLSCAN:就是所谓的“集合扫描”,下图有详解

<2> nReturned:就是说最后返回的num个数,从图中可以看到,就是最终返回了三条

<3> docsExamined:就是documentsExamined,检查了10个documents,而从返回上面的nReturned

从上面三个信息中我们可以得出,原来我examine 10 条数据,最终才返回3条,说明做了7条数据扫描的无用功
Stage状态分析
stage 描述
COLLSCAN 全表扫描
IXSCAN 扫描索引
FETCH 根据索引去检索指定document
SHARD_MERGE 将各个分片返回数据进行merge
SORT 表明在内存中进行了排序
LIMIT 使用limit限制返回数
SKIP 使用skip进行跳过
IDHACK 针对_id进行查询
SHARDING_FILTER 通过mongos对分片数据进行查询
COUNT 利用db.coll.explain().count()之类进行count运算
COUNTSCAN count不使用Index进行count时的stage返回
COUNT_SCAN count使用了Index进行count时的stage返回
SUBPLA 未使用到索引的$or查询的stage返回
TEXT 使用全文索引进行查询时候的stage返回
PROJECTION 限定返回字段时候stage的返回

那么这个时候问题就来了,该如何减少examine的documents呢?

(4) 索引查询

在这里插入图片描述
我们就可以进行针对性的建立索引,比如在quality字段之上,当我们执行完createindex之后,再次explain,4个重要的parameters就漂下来了:
<1> IXSCAN:这个时候再也不是所谓的COLLSCAN了,而是IndexScan,这就说明我们已经命中索引了。

<2> nReturned,totalDocsExamined,totalKeysExamined:从图中可以看到三个参数都是3,这就说明我们的mongodb查看了3个key,3个document,返回3个文档

匹配文档和被扫描文档数量之间的巨大差异意味着,要提高效率,可以使用索引对该查询进行优化。

发布了5 篇原创文章 · 获赞 4 · 访问量 1211
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 终极编程指南 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览