Today, Xiaobian uses the explain() method to analyze the use effect of indexes in the collection
1. Insert 100w records circularly first
for (var i = 0; i < 1000000; i++ ) { db.person.insert({"name":"test"+i, "cardNo":i}) }
2. Check the insertion effect
> db.person.find() { "_id" : ObjectId("5c7c9e15a795b984b42ad96b"), "name" : "test0", "cardNo" : 0 } { "_id" : ObjectId("5c7c9e15a795b984b42ad96c"), "name" : "test1", "cardNo" : 1 } { "_id" : ObjectId("5c7c9e15a795b984b42ad96d"), "name" : "test2", "cardNo" : 2 } { "_id" : ObjectId("5c7c9e15a795b984b42ad96e"), "name" : "test3", "cardNo" : 3 } { "_id" : ObjectId("5c7c9e15a795b984b42ad96f"), "name" : "test4", "cardNo" : 4 } { "_id" : ObjectId("5c7c9e15a795b984b42ad970"), "name" : "test5", "cardNo" : 5 } { "_id" : ObjectId("5c7c9e15a795b984b42ad971"), "name" : "test6", "cardNo" : 6 } { "_id" : ObjectId("5c7c9e15a795b984b42ad972"), "name" : "test7", "cardNo" : 7 } { "_id" : ObjectId("5c7c9e15a795b984b42ad973"), "name" : "test8", "cardNo" : 8 } { "_id" : ObjectId("5c7c9e15a795b984b42ad974"), "name" : "test9", "cardNo" : 9 } { "_id" : ObjectId("5c7c9e15a795b984b42ad975"), "name" : "test10", "cardNo" : 10 } { "_id" : ObjectId("5c7c9e15a795b984b42ad976"), "name" : "test11", "cardNo" : 11 } { "_id" : ObjectId("5c7c9e15a795b984b42ad977"), "name" : "test12", "cardNo" : 12 } { "_id" : ObjectId("5c7c9e15a795b984b42ad978"), "name" : "test13", "cardNo" : 13 } { "_id" : ObjectId("5c7c9e15a795b984b42ad979"), "name" : "test14", "cardNo" : 14 } { "_id" : ObjectId("5c7c9e15a795b984b42ad97a"), "name" : "test15", "cardNo" : 15 } { "_id" : ObjectId("5c7c9e15a795b984b42ad97b"), "name" : "test16", "cardNo" : 16 } { "_id" : ObjectId("5c7c9e15a795b984b42ad97c"), "name" : "test17", "cardNo" : 17 } { "_id" : ObjectId("5c7c9e15a795b984b42ad97d"), "name" : "test18", "cardNo" : 18 } { "_id" : ObjectId("5c7c9e15a795b984b42ad97e"), "name" : "test19", "cardNo" : 19 } Type "it" for more
3. Query analysis without index
> db.person.find({"name":"test890000"}).explain("executionStats") { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.person", "indexFilterSet" : false, "parsedQuery" : { "name" : { "$eq" : "test890000" } }, "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "name" : { "$eq" : "test890000" } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 1, "executionTimeMillis" : 389, "totalKeysExamined" : 0, "totalDocsExamined" : 1000000, "executionStages" : { "stage" : "COLLSCAN", "filter" : { "name" : { "$eq" : "test890000" } }, "nReturned" : 1, "executionTimeMillisEstimate" : 232, "works" : 1000002, "advanced" : 1, "needTime" : 1000000, "needYield" : 0, "saveState" : 7814, "restoreState" : 7814, "isEOF" : 1, "invalidates" : 0, "direction" : "forward", "docsExamined" : 1000000 } }, "serverInfo" : { "host" : "shengyulongdeMacBook-Pro-2.local", "port" : 27017, "version" : "4.0.3", "gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c" }, "ok" : 1 }
4. Create an ascending index for the name field
> db.person.createIndex({"name":1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
5.explain view index analysis
> db.person.find({"name":"test890000"}).explain("executionStats") { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.person", "indexFilterSet" : false, "parsedQuery" : { "name" : { "$eq" : "test890000" } }, "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "name" : 1 }, "indexName" : "name_1", "isMultiKey" : false, "multiKeyPaths" : { "name" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "name" : [ "[\"test890000\", \"test890000\"]" ] } } }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 1, "executionTimeMillis" : 1, "totalKeysExamined" : 1, "totalDocsExamined" : 1, "executionStages" : { "stage" : "FETCH", "nReturned" : 1, "executionTimeMillisEstimate" : 0, "works" : 2, "advanced" : 1, "needTime" : 0, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "invalidates" : 0, "docsExamined" : 1, "alreadyHasObj" : 0, "inputStage" : { "stage" : "IXSCAN", "nReturned" : 1, "executionTimeMillisEstimate" : 0, "works" : 2, "advanced" : 1, "needTime" : 0, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "invalidates" : 0, "keyPattern" : { "name" : 1 }, "indexName" : "name_1", "isMultiKey" : false, "multiKeyPaths" : { "name" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "name" : [ "[\"test890000\", \"test890000\"]" ] }, "keysExamined" : 1, "seeks" : 1, "dupsTested" : 0, "dupsDropped" : 0, "seenInvalidated" : 0 } } }, "serverInfo" : { "host" : "shengyulongdeMacBook-Pro-2.local", "port" : 27017, "version" : "4.0.3", "gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c" }, "ok" : 1 }
- executionStats.nReturned: number of documents returned
- executionStats.executionTimeMillis: execution time, unit (ms)
- executionStats.totalKeysExamined: index scan entry.
- executionStats.totalDocsExamined: document scan entry
comparative analysis
Use index | Do not use index | |
---|---|---|
Search time | 1ms | 389ms |
Index scan entry | 1 | 0 |
Document scan entry | 1 | 1000000 |
There is a big difference between using index and not using index!!!