In typical Mongodb database query scenarios, index plays a very important role. If there is no index, Mongodb needs to scan the entire collection to find a matching document, which is very expensive.

Mongodb index uses b-tree this special data structure, with the help of the index Mongodb can efficiently match the data to be queried, as shown in the following figure (from the official) :

Score index not only supports range query efficiently, but also enables MongoDB to return sorted data efficiently.

Mongodb indexes are similar to other database systems. Mongodb indexes are defined at the collection level and can be indexed to any single field or any sub-field.

The default_id index

When a collection is created, Mongodb creates a default unique index based on _id as the primary key of document, which cannot be deleted.

Mongo support a variety of ways to create indexes, see the specific way to create the official documentation docs.mongodb.com/manual/inde…

Single field index

Single field index is the simplest type of index in Mongodb. Different from MySQL, Mongodb has a ascending or descending index.

For a single field index, however, the order of the index doesn’t matter, because MongoDB supports traversing a single field index in any order.

Create a Records collection here:

{"_id": ObjectId(" 570c04a4AD233577f97dc459 "), "score": 1034, "location": {state: "NY", city: "New York"}} Copy the codeCopy the code

Then create a single field index:

Db.records.createindex ({score: 1}) copies the codeCopy the code

The above statement creates a ascending index on the score field of the collection, which supports the following query:

Db.records. find({score: 2}) db.records.find({score: {$gt: 10}}) copies the codeCopy the code

The above two queries can be analyzed using MongoDB’s Explain:

Db.records.find ({score:2}).explain('executionStats') copies the codeCopy the code

single index on embedded field

MongoDB also supports index creation for embedded fields:

Db.records.createindex ({"location.state": 1}) copies the codeCopy the code

The embedded Index above supports the following queries:

db.records.find( { "location.state": "CA" } ) db.records.find( { "location.city": "Albany", "location.state": "NY"}) copies the codeCopy the code

sort on single index

For single index, since MongoDB index itself supports sequential lookup, so for single index

db.records.find().sort( { score: 1 } ) db.records.find().sort( { score: 1}) db. Records. The find ({score: {$lte: 100}}), sort (} {score: - 1) duplicate codeCopy the code

All of these queries are indexed.

Compound index

Mongodb supports indexing multiple fields, called compound Indexes. The order of fields in a Compound Index has a critical impact on index performance, such as indexes {userID :1, score:-1} sorting first by userID and then by score within each userID.

Create a Compound index

Create a Products collection here:

{ "_id": ObjectId(...) , "item": "Banana", "category": ["food", "produce", "grocery"], "location": "4th Street Store", "stock": 4, "type": "Cases"} copies the codeCopy the code

Then create a compound Index:

Db.products.createindex ({"item": 1, "stock": 1}) copies the codeCopy the code

The documents referenced by index are sorted first by item, and then, within each item, by stock. The following statements satisfy the index:

Db.products.find ({item: "Banana"}) db.products.find({item: "Banana", stock: {$gt: 5}}) copies the codeCopy the code

The condition {item: “Banana”} is satisfied because the query satisfies the prefix principle.

Using a compound index needs to meet the prefix principle

Index prefix refers to the left prefix subset of Index fields. Consider the following indexes:

{"item": 1, "location": 1, "stock": 1} Copies the codeCopy the code

This index contains the following index prefix:

{item: 1} {item: 1, location: 1} copies the codeCopy the code

So you can use compound Index statements that satisfy the index prefix principle:

db.products.find( { item: "Banana" } ) db.products.find( { item: "Banana",location:"4th Street Store"}) db.products.find({item: "Banana",location:"4th Street Store",stock:4}) copy codeCopy the code

If the index prefix is not specified, the index cannot be used, as in the following field query:

  • the location field
  • the stock field
  • the location and stock fields

Due to the index prefix, if a collection has both {a:1, b:1} and {a:1} indexes, the single index can be removed if the two indexes are not sparse or unique.

Sort on Compound index

As mentioned earlier, the sort order of single indexes doesn’t matter, but compound indexes are completely different.

Consider the following scenarios:

Db.events.find ().sort({username: 1, date: -1}) copies the codeCopy the code

The events collection has a descending order for the result (username) and a descending order for the result (date descending).

Db.events.find ().sort({username: -1, date: 1}) copies the codeCopy the code

Order by descending (select descending from user);

Db.events.createindex ({"username" : 1, "date" : -1}) replicates the codeCopy the code

Both types of queries are supported, but the following are not:

Db.events.find ().sort({username: 1, date: 1}) copies the codeCopy the code

That is, the order of sort must be the same as that in which the index was created

{ “username” : 1, “date” : -1 } { “username” : 1, “date” : 1 }
sort( { username: 1, date: -1 } ) support Does not support
sort( { username: -1, date: 1 } ) support Does not support
sort( { username: 1, date: 1 } ) Does not support support
sort( { username: -1, date: -1 } ) Does not support support

The sort order must be the same as that of the index, or even if reversed. The following table clearly lists the types of query statements that compound Index satisfies:

query index
db.data.find().sort( { a: 1 } ) { a: 1 }
db.data.find().sort( { a: -1 } ) { a: 1 }
db.data.find().sort( { a: 1, b: 1 } ) { a: 1, b: 1 }
db.data.find().sort( { a: -1, b: -1 } ) { a: 1, b: 1 }
db.data.find().sort( { a: 1, b: 1, c: 1 } ) { a: 1, b: 1, c: 1 }
db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } ) { a: 1, b: 1 }

Sort of non-index prefix

Consider the index {a: 1, b: 1, C: 1, d: 1}, even if the sorted field does not meet the index prefix, it is ok, but the precondition is that the index field before the sorted field must be equivalent condition.

Example Index Prefix
r1 db.data.find( { a: 5 } ).sort( { b: 1, c: 1 } ) { a: 1 , b: 1, c: 1 }
r2 db.data.find( { b: 3, a: 4 } ).sort( { c: 1 } ) { a: 1, b: 1, c: 1 }
r3 db.data.find( { a: 5, b: { $lt: 3} } ).sort( { b: 1 } ) { a: 1, b: 1 }

Table R1 above has a sort field b and c, a is an index field and can be used before b and C; In the sorting of R3, B is the range query, but A before B also uses the equivalence condition, that is, as long as the field before the sorting of fields meets the equivalence condition, the other fields can be any condition.

How to build the correct index

The previous article basically covered the main index knowledge needed for daily use of MongoDB, but how to establish the correct index?

Analyze query statements using Explain

By default, MongoDB provides statements similar to MySQL Explain to analyze query statements to help us correctly build indexes. When building indexes, we need to analyze various query conditions against Explain.

Understand the effect of field order on indexes

The real function of the index is to help us limit the selection of data, such as Compound Index how to determine the order of multiple feild, should be the first field that can maximize the narrowing of the search range of data, so that if the first field can quickly narrow the search range of data, Then subsequent feild matches will have fewer rows. Consider statements:

{'online_time': {'$lte': present}, 'offline_time': {'$gt': present}, 'online': 1, 'orientation': 'quality', 'id': {'$gt': max_id}} Copy the codeCopy the code

Consider the following indexes

The index nscanded
r1 {start_time:1, end_time: 1, origin: 1, id: 1, orientation: 1} 12959
r2 {start_time:1, end_time: 1, origin: 1, orientation: 1, id: 1} 2700

The difference in the order of field ID and orientation will lead to a huge difference in the number of documents to be scanned, indicating that the two pairs have a great difference in the restricted scope of data. Therefore, priority should be given to the index order that can maximize the limited scope of data.

Monitoring Slow Query

Always analyze the slow queries generated by the generation environment in the first time to find and solve problems in advance.

Wecatch: Juejin. Im/Post / 5ad1D2… The copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.