Optimize a simple example
This part mainly explains how to optimize the performance of MongoDB.
Let’s take a concrete example. Suppose our task is to display the front page of the blog – we want to display the last 10 posts. ts is the time field.
The statement is as follows
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());}
Optimization #1: Create Index
The first optimization is to create an index on ts for quick sorting.
db.posts.ensureIndex({ts:1});
Using an index, the database can sort based on the index information, without looking at each document directly. It’s faster to do this.
Optimization #2: Limit results
MongoDB cursors return a set of documents, which we call chunks.
This chunk may contain more than 10 objects. The extra objects are wasteful for our needs,
A waste of network bandwidth and application server and database resources.
We know the number of results we want, so we don’t need all of them. We can use the limit() method
articles = db.posts.find().sort({ts:-1}).limit(10);
// Up to 10 entries
Now, we returned 10 entries from the client.
Optimization #3: Query related fields
Post objects are very large, like post text and comment arrays. A better way is to only query the fields we want to use.
articles = db.posts.find({}, {ts:1,title:1,author:1,abstract:1}).sort({ts:-1}).limit(10);
articles.forEach( function(post) { print(post.getSummary()); } );
The above getSummary() method assumes that the field value returned by the find() method can be obtained
Note that if you select a field to query, a partial object will be returned. This object cannot be updated directly. as follows
a_post = db.posts.findOne({}, Post.summaryFields);
a_post.x = 3;
db.posts.save(a_post); // Error, throw exception
Using Profiler
MongoDB has a database profiler that shows the performance of each operation.
Using the profiler you can see which queries or writes are slow.
For example, use this information to know when an index is needed. See Database Profiler for details.
Use count() optimization statement
Accelerating statement speed depends on count(), create an index, and call count().
db.posts.ensureIndex({author:1});
db.posts.find({author:”george”}).count();
Increment Operations
MongoDB supports incremental operations on simple object fields;
Basically, this operation increments a field in the server document”.
This is much faster than the method of “get a document, update this field and save it to the server”,
And it is more useful for real-time counters. See Updates for details.
Fixed size collection.
MongoDB provides a special collection that allocates storage space in advance.
Items are saved in a fixed order and are not indexed. And writing and reading are very high speed.
Storage is set for saving log files. See Capped Collections for details
Server Side Code Execution
Maybe sometimes for high performance, to avoid back and forth communication between the client and the server, you need to execute code directly on the server.
See Server-Side Processing for this section.
Explain tool
To view detailed performance information of a query statement, the best way is to use the explain method.
The returned result is some information about the entire query execution.
When using the shell, you can call the explain() method of the cursor.
db.collection.find(query).explain();
The returned information is as follows
{“cursor” : “BasicCursor”,
“indexBounds” : [ ],
“nscanned” : 57594,
“nscannedObjects” : 57594,
“nYields” : 2 ,
“n” : 3 ,
“millis” : 108,
“indexOnly” : false}
The actual result can know the type of cursor, the number of data scanned by DB, the number of returned data, and the number of milliseconds for execution.
nscanned – the number of scanned data. This data may be an object or an index key.
If “covered index” is called, nscanned is higher than nscannedObjects.
nscannedObjects – the number of scanned objects.
nYields – The number of locks generated by the query.
indexOnly – whether covered index is used.
Hint
While the MongoDB query optimizer generally works pretty well, it is also possible to use hints to force MongoDB to use a specific index.
This method someIt will improve the performance under the condition of ��. An indexed collection and executes a multi-column query (some columns are already indexed).
Pass in a specified index to force the query to use.
db.collection.find({user:u, foo:d}).hint({user:1});
Make sure the index is created. In the above example, first you make sure that the index has been created. Please use ensureIndex() to create an index. |
Another example, with an index on {a:1, b:1} named “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”);
To force a query without an index, (doing a table scan), use:
> db.collection.find().hint({$natural:1})