1.索引简介
数据库索引类似于图书索引。有了索引便不需要浏览整本书,而是可以采取一种快捷方式,只查看一个有内容引用的有序列表。这使得 MongoDB 的查找速度提高了好几个数量级。不使用索引的查询称为集合扫描,这意味着服务器端必须“浏览整本书”才能得到查询的结果。这个过程基本上类似于在一本没有索引的书中寻找信息:从第 1 页开始,通读整本书。通常来说,我们希望避免让服务器端执行集合扫描,因为对于大集合来说,该过程非常缓慢。首先创建一个100万个文档的集合
for (i=0; i<1000000; i++) { db.users2.insertOne( { "i" : i, "username" : "user"+i, "age" : Math.floor(Math.random()*120), "created" : new Date() } ); }
查看执行计划:
> db.users2.find({"username": "user101"}).explain("executionStats") { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "wang.users2", "indexFilterSet" : false, "parsedQuery" : { "username" : { "$eq" : "user101" } }, "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "username" : { "$eq" : "user101" } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 1, #返回的结果数 "executionTimeMillis" : 533, #执行查询所用的毫秒数 "totalKeysExamined" : 0, "totalDocsExamined" : 1000000, #扫描的文档数 "executionStages" : { "stage" : "COLLSCAN", "filter" : { "username" : { "$eq" : "user101" } }, "nReturned" : 1, "executionTimeMillisEstimate" : 48, "works" : 1000002, "advanced" : 1, "needTime" : 1000000, "needYield" : 0, "saveState" : 1000, "restoreState" : 1000, "isEOF" : 1, "direction" : "forward", "docsExamined" : 1000000 } }, "serverInfo" : { "host" : "db10", "port" : 27017, "version" : "4.4.14", "gitVersion" : "0b0843af97c3ec9d2c0995152d96d2aad725aab7" }, "ok" : 1 } >
(1).创建索引
现在尝试在 "username" 字段上创建一个索引。要创建索引,需要使用 createIndex 集合方法:
db.users2.createIndex({"username" : 1})
创建索引只需几秒的时间,除非集合特别大。如果 createIndex 调用在几秒后没有返回,则可以运行 db.currentOp()(在另一个 shell 中)或检查 mongod 的日志以查看索引创建的进度。
索引创建完成后,再次执行最初的查询:
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, "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, "keyPattern" : { "username" : 1 }, "indexName" : "username_1", "isMultiKey" : false, "multiKeyPaths" : { "username" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "username" : [ "[\"user101\", \"user101\"]" ] }, "keysExamined" : 1, "seeks" : 1, "dupsTested" : 0, "dupsDropped" : 0 } } }
索引可以显著缩短查询时间。然而,使用索引是有代价的:修改索引字段的写操作(插入、更新和删除)会花费更长的时间。这是因为在更改数据时,除了更新文档,MongoDB还必须更新索引。通常来说,这个代价是值得的。关键是找出要索引的字段。
(2).复合索引简介
索引的目的是使查询尽可能高效。对于许多查询模式来说,在两个或更多的键上创建索引是必要的。例如,索引会将其所有值按顺序保存,因此按照索引键对文档进行排序的速度要快得多。然而,索引只有在作为排序的前缀时才有助于排序。例如,"username" 上的索引对下面这种排序就没什么帮助:
db.users.find().sort({"age" : 1, "username" : 1})
这里是先根据 "age",然后再根据 "username" 进行排序的,所以严格按 "username" 排序并没有什么帮助。要优化这种排序,可以在 "age" 和 "username" 上创建索引:
db.users.createIndex({"age" : 1, "username" : 1})
这称为复合索引(compound index)。如果查询中有多个排序方向或者查询条件中有多个键,那么这个索引会非常有用。复合索引是创建在多个字段上的索引。
假设有如下所示的一个 users3 集合,并且要执行不带排序(称为自然顺序)的查询:
官方地址:https://www.mongodb.com/docs/upcoming/indexes/
标签:username,mongodb4.4,创建,查询,索引,user101,排序 From: https://www.cnblogs.com/Yongzhouunknown/p/16585770.html