MongoDB性能优化
查询操作的优化
假设我们按照时间戳查询最近发表的10篇博客文章:
articles = db.posts.find().sort({ts:-1}); // get blog posts in reverse time order
for (var i=0; i< 10; i++) {
print(articles[i].getSummary());
}
优化#1: 创建索引
在查询条件的字段上,或者排序条件的字段上创建索引,可以显著提高执行效率:
sureIndex({ts:1});
优化#2: 限定返回结果条数
使用limit()限定返回结果集的大小,可以减少database server的资源消耗,可以减少网络传输数据量。
articles = db.posts.find().sort({ts:-1}).limit(10); // 10 results maximum
优化#3: 只查询使用到的字段,而不查询所有字段
The blog post object may be very large, with the post text and comments embedded. Much better performance will be achieved by selecting only the fields we need:
在本例中,博客日志记录内容可能非常大,而且还包括了评论内容(作为embeded文档)。所以只查询使用的字段,比查询所有字段效率更高:
articles = db.posts.find({},
{ts:1,title:1,author:1,abstract:1}).sort({ts:-1}).limit(10);
注意:如果只查询部分字段的话,不能用返回的对象直接更新数据库。下面的代码是错误的:
a_post = db.posts.findOne({}, Post.summaryFields);
a_post.x = 3;
db.posts.save(a_post); // error, exception thrown
Using the Profiler
MongoDB有一个数据库优化工具Database Profiler,这个工具能检测数据库操作的性能。用个工具可以发现query或者write操作中执行效率低的,从而针对这些操作进行优化。
优化count()查询操作
在count()操作的查询条件字段上创建索引,可以提高效率。
sureIndex({author:1});
db.posts.find({author:"george"}).count();
Increment操作
更新字段的值时,使用Increment操作效率更高。Increment操作比先查询出数据,然后修改数据执行update操作的效率更高。
Circular Fixed Size Collections
apped Collections比普通Collections的读写效率高。Capped Collections是高效率的Collection 类型,它有如下特点:
●固定大小;Capped Collections必须事先创建,并设置大小:
●Capped Collections可以insert和update操作;不能delete操作。只能用drop()
方法删除整个Collection。
●默认基于Insert的次序排序的。如果查询时没有排序,则总是按照insert的顺序返回。
●FIFO。如果超过了Collection的限定大小,则用FIFO算法,新记录将替代最先insert
的记录。
Server Side Code Execution
Server-Side Processing类似于SQL数据库的存储过程,使用Server-Side Processing可以减小网络通讯的开销。
Explain
使用explain,MongoDB显示操作的explain plan。可以根据explain plan进行优化。
provides information such as the following:
{
"cursor" : "BasicCursor",
"indexBounds" : [ ],
"nscanned" : 57594,
"nscannedObjects" : 57594,
"n" : 3 ,
"millis" : 108
}
Cursor:BasicCursor表示没有用到索引(类似SQL数据库的全部扫描。)BtreeCursor表示使用了索引。
indexBounds:使用到的索引;
nscanned:扫描的总记录数;
nscannedObjects:扫描的总对象数;
n:命中的总记录数;
millis:执行的时间长度。
This will tell you the type of cursor used (BtreeCursor is another type – which will include a lower & upper bound), the number of records the DB had to examine as part of this query, the number of records returned by the query, and the time in milliseconds the query took to execute.
Hint
一般情况下Mongo query optimizer都工作良好,但有些情况下使用hint()可以提高操作效率。Hint可以强制要求查询操作使用某个索引。例如,如果要查询多个字段的值,如果在其中一个字段上有索引,可以使用hint:
Optimizing Object IDs
The _id field in MongoDB objects is very important and is always indexed. This page lists some recommendations.
sort of in orderUse the collections 'natural primary key' in the _id field.
如果有自己的主键列,则使用自己的主键列作为ID。这样可以节约空间,也不需要创建额外的索引。
Use _id values that are roughly in ascending order.
_ID列(主键列)如果按照大小顺序生成,则可以提高效率(MongoDB内部插入b-tree时速度更快)
Store GUIDs as BinData, rather than as strings
如果是UUID类型的主键,使用BinaryData比使用String存储效率高。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论