首页 > 数据库 >mongodb4.4索引

mongodb4.4索引

时间:2022-08-14 17:13:51浏览次数:45  
标签:username mongodb4.4 创建 查询 索引 user101 排序

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

相关文章

  • 搞定面试官 - 你可以介绍一下在 MySQL 中,哪些情况下 索引会失效嘛?
    大家好,我是程序员啊粥,前边给大家分享了*MySQLInnoDB索引模型在MySQLInnoDB中,为什么delete删除数据之后表数据文件大小没有变如何计算一个索引的长度如何查看......
  • SQL索引
    语法:UNIQUE(DISTINCT):惟一性索引,不允许表中不同的行在索引列上取相同值。若已有相同值存在,则系统给出相关信息,不建此索引。CLUSTERED/NONCLUSTERED:聚集和非聚集索......
  • Six---pytorch学习---索引与切片
    pytorch学习(3)索引与切片普通索引冒号索引(切片)index_select选择特定索引masked_select选择符合条件的索引take索引普通索引index(有负索引)importtorcha......