MongoDB索引的类型有哪些?怎样做索引操作?
Admin 2021-05-26 群英技术资讯 798 次浏览
接触过SQL都知道,索引是很重要的内容。在MongoDB中索引也是很重要的,数据库的索引能够提高查询操作的性能,能快速获取我们想要的介绍。下面我们就一起来了解一下MongoDB索引。
1、简介
它就像是一本书的目录,如果没有它,我们就需要对整个书籍进行查找来获取需要的结果,即所说的全盘扫描;而有了目录(索引)之后就可以通过它帮我们定位到目标所在的位置,快速的获取我们想要的结果。
2、演示
第一步,向用户集合users中插入100W条数据
var insertUsers = function() { var start = new Date().getTime(); for (var i = 1; i <= 1000000; i++) { db.users.insert({ "userid": i, "username": "wjg" + i, "age": Math.floor(Math.random() * 100), //年龄为0~99的随机整数 "createdate": new Date() }) } var end = new Date().getTime(); print("插入100W条数据共耗时" + (end - start) / 1000 + "秒"); }
LZ的渣渣I3和4G内存总共耗时了484.623秒,约8分多钟。任务管理器里边可以很清楚的看到当时CPU、内存和磁盘使用率都普遍的增高。
第二步:查询用户名为“wjg465413”的文档对象
db.users.find({username:"wjg465413"}).explain("allPlansExecution") { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.users", "indexFilterSet" : false, "parsedQuery" : { "username" : { "$eq" : "wjg465413" } }, "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "username" : { "$eq" : "wjg465413" } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 1, "executionTimeMillis" : 865, "totalKeysExamined" : 0, "totalDocsExamined" : 1000000, "executionStages" : { "stage" : "COLLSCAN", "filter" : { "username" : { "$eq" : "wjg465413" } }, "nReturned" : 1, "executionTimeMillisEstimate" : 770, "works" : 1000002, "advanced" : 1, "needTime" : 1000000, "needFetch" : 0, "saveState" : 7813, "restoreState" : 7813, "isEOF" : 1, "invalidates" : 0, "direction" : "forward", "docsExamined" : 1000000 }, "allPlansExecution" : [ ] }, "serverInfo" : { "host" : "Jack", "port" : 27017, "version" : "3.0.3", "gitVersion" : "b40106b36eecd1b4407eb1ad1af6bc60593c6105" }, "ok" : 1 }
说明:这里的explain方法相当于查询计划,它会返回给你查询过程的详细信息。它的参数有三种模式:“queryPlanner”(查询计划[默认])、“executionStats”(执行状态)和“allPlansExecution”(所有执行计划),这里我们只关注它返回给我们的以下几个信息。
"executionTimeMillis" : 865 //执行的毫秒数 注:如果你是第一次执行,可能会花费更长的时间 "totalDocsExamined" : 1000000 //共检查的文档数
第三步:在用户名“username”字段上加上索引
db.users.createIndex({ "username" : 1 })
重新执行上次的查询操作
db.users.find({username:"wjg465413"}).explain("allPlansExecution") { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.users", "indexFilterSet" : false, "parsedQuery" : { "username" : { "$eq" : "wjg465413" } }, "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "username" : 1 }, "indexName" : "username_1", "isMultiKey" : false, "direction" : "forward", "indexBounds" : { "username" : [ "[\"wjg465413\", \"wjg465413\"]" ] } } }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 1, "executionTimeMillis" : 53, "totalKeysExamined" : 1, "totalDocsExamined" : 1, "executionStages" : { "stage" : "FETCH", "nReturned" : 1, "executionTimeMillisEstimate" : 0, "works" : 2, "advanced" : 1, "needTime" : 0, "needFetch" : 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, "needFetch" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "invalidates" : 0, "keyPattern" : { "username" : 1 }, "indexName" : "username_1", "isMultiKey" : false, "direction" : "forward", "indexBounds" : { "username" : [ "[\"wjg465413\", \"wjg465413\"]" ] }, "keysExamined" : 1, "dupsTested" : 0, "dupsDropped" : 0, "seenInvalidated" : 0, "matchTested" : 0 } }, "allPlansExecution" : [ ] }, "serverInfo" : { "host" : "Jack", "port" : 27017, "version" : "3.0.3", "gitVersion" : "b40106b36eecd1b4407eb1ad1af6bc60593c6105" }, "ok" : 1 }
可以看到两次的查询计划有很大的差别,我们还是着重看下那两个属性值。
"executionTimeMillis" : 53 //执行的毫秒数 "totalDocsExamined" : 1 //共检查的文档数
加过索引之后查询这个文档所耗费的时间仅仅为53毫秒,并且扫描一次直接定位,性能提升了16倍。可见合理使用索引的重要性!
注:“_id”字段是Mongo为我们默认添加的索引,而且是唯一索引,保证了数据的唯一性,不可以移除。另外,使用limit(1)限制查询结果的数量也可以提高查询速度
3、索引的类型
a)、单一索引:可以在数据集上任意一个字段上建立索引,包括普通的属性键、内嵌文档以及内嵌文档中的属性键。
db.users.createIndex({ "username" : 1 }) //普通属性键的索引 //假设class是一个内嵌的文档 db.users.createIndex({ "class" : 1 }) //内嵌文档的索引 db.users.createIndex({ "class.classname" : 1 }) //内嵌文档中的属性键索引
索引方向:1表示升序,-1表示降序
b)、复合索引:以多个属性键为基础而建立得索引
db.users.createIndex({ "username" : 1, "age" : -1, "userid" : 1 }) //在“username”、“age”和“userid”上建立复合索引
索引前缀:通过建立上边的复合索引之后,Mongo就相当于同时拥有了三个索引一样,分别是{"username" : 1},{"username" : 1, "age" : -1}和{"username" : 1, "age" : -1, "userid" : 1},但是像{"age" : -1},{"userid" : 1}或者{"age" : -1, "userid" : 1}这三个索引并不会起作用。所以它会使用包含了前缀(首个)的索引的作为复合索引
c)、多键索引:为数组中的多个值建立索引以实现高效查询。
注:Ⅰ、不允许在多个数组上建立复合索引
Ⅱ、不能指定片键作为多键索引
Ⅲ、哈希索引不能是多键
Ⅳ、多键索引不支持覆盖查询
d)、地理空间索引和查询:Mongo提供了两种曲面类型的索引:2dsphere索引和2d索引。查询类型包括:包含(inclusion),交叉(intersection)和接近(proximity)
e)、文本索引:用来支持查询包含了字符串或者字符串数组的文档
db.users.createIndex({"username" : "text"})
注:文本索引不支持排序并且一个复合文本索引不能再包含其他任何索引了
f)、哈希索引:它可以在使用了哈希片键进行分片的数据集上进行索引,支持相等查询,但是不支持范围查询
db.users.createIndex({"username" : "hashed"})
4、索引特性
a)、TTL(Time-To-Live)索引:是一种具有生命周期的索引,它允许为每一个文档设置一个超时时间
db.users.createIndex({ "createdate" : 1 },{ "expireAfterSecs" : 60*60*24 })
说明:在“createdate”字段上建立一个TTL索引,当这个自段存在并且是日期类型,当服务器时间比“createdate”字段的时间晚60*60*24秒,即24小时时,文档就会被删除
b)、唯一索引:确保集合的每一个文档的指定键都有唯一值
db.users.createIndex({"username" : 1}, {"unique" : true})
c)、稀疏索引:Mongo里边的null会被看做值,如果有一个可能存在也可能不存在的字段,我们可以使用稀疏索引
db.users.createIndex({"age" : 1},{"sparse" : true})
4、索引操作
a)、查看所有索引
db.users.getIndexes()
b)、移除索引
db.users.dropIndex({"createdate1" : 1 })
c)、移除所有索引
db.users.dropIndexes()
d)、重建索引
db.users.reIndex()
说明:该操作会先删除所有索引,包括“_id”,然后重新创建所有索引
以上就是关于MongoDB索引的介绍,现在大家对于MongoDB索引类型,操作等等应该都有一定的了解,希望大家阅读完这篇文章能有所收获,更多MongoDB索引内容,大家可以关注其他文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
在数据库学习中,索引是一定要掌握的内容,因此这篇文章就给大家介绍一下关于MongoDB索引的操作,包括创建、查看、删除等等,有这方面学习需要的朋友可以看看。
MongoDB Limit与Skip方法 MongoDB Limit() 方法 如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。 语法 limit()方法基本语法如下所示: >db.COLLECTION_NAME.find().limit(NUMBER) 实例 集合 col 中的数据如下: { �..
这篇文章给大家分享的是一些MongoDB优化方法和MongoDB优化需要注意的地方,具有一定的参考价值,感兴趣的朋友可以看看,下面就跟随小编一起来看看吧。
mongodb快的原因:写操作快是因为只要在内存里完成就可以返回给应用程序。读操作快是因为MongoDB要求你常用的数据可以在内存里装下,读取时只需读取内存即可。
这篇文章主要介绍了 mongoDB 实现主从读写分离实现的实例代码的相关资料,需要的朋友可以参考下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008