博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MongoDB 优化
阅读量:4980 次
发布时间:2019-06-12

本文共 2574 字,大约阅读时间需要 8 分钟。

优化一个简单的例子

这部分主要讲解如何优化MongoDB的性能。

让我们举个具体示例。假使我们的任务是现实blog的首页-我们希望现实最近发布的10条posts。ts为时间字段。

语句如下

articles = db.posts.find().sort({ts:-1}); // get blog posts in reverse time orderfor (var i=0; i< 10; i++) { print(articles[i].getSummary());} 优化 #1: 创建索引

第一个优化就是要在ts上创建索引,用来快速排序。

db.posts.ensureIndex({ts:1});

使用索引,数据库就可以基于索引信息排序,不会直接查看每个document。这样做更快。

优化#2: 限定结果

MongoDB游标返回一组document,我们叫这个为chunks。

这chunk可能包含超过10个对象。额外的对象对于我们的需求是浪费,

浪费了网络带宽和应用服务器以及数据库的资源。

我们知道想要结果的个数,那么就不需要所有的结果。我们可以使用limit()方法

articles = db.posts.find().sort({ts:-1}).limit(10); // 最多10条

现在,我们从客户端返回了10条。

优化 #3: 查询相关的字段

post对象非常大, 如post文本和评论数组。 比较好的方式是只查询我们要用到的字段。

articles = db.posts.find({}, {ts:1,title:1,author:1,abstract:1}).sort({ts:-1}).limit(10); articles.forEach( function(post) { print(post.getSummary()); } );

上面的getSummary()方法假使是可以获得find()方法返回的字段值

注意,如果你选择了要查询的字段,那么返回的就是部分对象。这个对象并不能直接进行更新。如下

a_post = db.posts.findOne({}, Post.summaryFields); a_post.x = 3; db.posts.save(a_post); // 错误,抛出异常使用 Profiler

MongoDB有一个数据库的 profiler,用来显示每个操作的性能。

使用profiler你可以查看到哪些查询或者写入的速度比较慢。

举个例子,使用这些信息可以知道什么时候需要索引。详情查看  。

 Use count()优化语句

加速语句速度依赖于count(),创建一个索引,调用count()。

db.posts.ensureIndex({author:1}); db.posts.find({author:"george"}).count(); 增量操作Increment Operations

MongoDB 支持简单对象字段的增量操作; 

基本上来说, 这个操作就是 在服务器document中增量一个字段"。

这个要比"获取一个document,更新这个字段并且在保存会服务器"这个方法快很多,

并且对于实时的计数器更为有用。详情请看   。

固定大小的collection。

MongoDB提供了一个特殊的collection,它提前分配好了存储空间。

保存的项都是固定顺序的,并且没有索引。而且写入和读取是非常高速的。

存储是为了保存日志文件所设置的。详情查看  

服务端代码执行Server Side Code Execution

也许有的时候为了高性能,避免客户端和服务端来回通信,需要直接在服务端执行代码。

这部分查看  。

Explain工具

要想查看查询语句的详细性能信息,最好的方法就是使用explain方法。

返回的结果就是整个查询执行的一些信息。

当使用shell的时候,可以调用cursor的explain() 方法。

db.collection.find(query).explain();

返回的信息如下

{"cursor" : "BasicCursor", "indexBounds" : [ ], "nscanned" : 57594, "nscannedObjects" : 57594, "nYields" : 2 , "n" : 3 , "millis" : 108, "indexOnly" : false}

现实结果可以得知cursor的类型,DB扫描的数据数,返回的数据数,还有执行的毫秒数。

nscanned - 扫描的数据条数。这个数据可能是对象也可能是索引的键。 如果"覆盖索引(covered index)"被调用了,nscanned 要高于nscannedObjects. nscannedObjects - 扫描对象的数。 nYields - 查询所产生的锁的个数。 indexOnly - 是否使用了covered index。

 

Hint

虽然MongoDB查询优化器一般工作的很不错,但是也可以使用hints来强迫MongoDB使用一个指定的索引。

这种方法某些情形下会提升性能。 一个有索引的collection并且执行一个多字段的查询(一些字段已经索引了)。

传入一个指定的索引,强迫查询进行使用。

 

db.collection.find({user:u, foo:d}).hint({user:1});

确定创建了索引。
上面的例子,首先你确定索引已经创建了。请使用ensureIndex()创建索引。

 

其他的例子,有个在 {a:1, b:1} 上的索引,名称为"a_1_b_1":

db.collection.find({a:4,b:5,c:6}).hint({a:1,b:1}); db.collection.find({a:4,b:5,c:6}).hint("a_1_b_1");

强迫查询不适用索引, (做一个表的扫描), 使用:

> db.collection.find().hint({$natural:1})

转载于:https://www.cnblogs.com/beimu/p/4228842.html

你可能感兴趣的文章
HDU6203 ping ping ping
查看>>
Fireworks基本使用
查看>>
Java基础常见英语词汇
查看>>
nginx启动、关闭命令、重启nginx报错open() "/var/run/nginx/nginx.pid" failed
查看>>
UINavigationController的视图层理关系
查看>>
组件:slot插槽
查看>>
Nginx配置文件nginx.conf中文详解(转)
查看>>
POJ 1308 Is It A Tree?(并查集)
查看>>
N进制到M进制的转换问题
查看>>
php PDO (转载)
查看>>
[置顶] 一名优秀的程序设计师是如何管理知识的?
查看>>
highcharts 图表实例
查看>>
highcharts曲线图
查看>>
extjs动态改变样式
查看>>
宏定义
查看>>
笔记:git基本操作
查看>>
生成php所需要的APNS Service pem证书的步骤
查看>>
HOT SUMMER 每天都是不一样,积极的去感受生活 C#关闭IE相应的窗口 .
查看>>
optionMenu-普通菜单使用
查看>>
【MemSQL Start[c]UP 3.0 - Round 1 C】 Pie Rules
查看>>