首页 > 数据库 >MongoDB 基础(三)mongodb 中的索引使用

MongoDB 基础(三)mongodb 中的索引使用

时间:2023-01-27 14:02:07浏览次数:79  
标签:5000 MongoDB db find 索引 tab mongodb id


MongoDB中的索引和其他数据库索引类似,也是使用B-Tree结构。MongoDB的索引是在collection级别上的,并且支持在任何列或者集合内的文档的子列中创建索引。

 

下面是官方给出的一个使用索引查询和排序的一个结构图。


MongoDB 基础(三)mongodb 中的索引使用_Boo


所有的MongoDB集合默认都有一个唯一索引在字段“_id”上,如果应用程序没有为 “_id”列定义一个值,MongoDB将创建一个带有ObjectId值的列。(ObjectId是基于 时间、计算机ID、进程ID、本地进程计数器 生成的)


MongoDB 基础(三)mongodb 中的索引使用_默认值_02


MongoDB 同样支持在一列或多列上创建升序或降序索引。

MongoDB还可以创建 多键索引、数组索引、空间索引、text索引、哈希索引,其属性可以是唯一性索引、稀疏性索引、TTL(time to live)索引。

 

索引的限制:

索引名称不能超过128个字符

每个集合不能超过64个索引

复合索引不能超过31列



MongoDB 索引语法

db.collection.createIndex({ <field>: < 1 or -1 > })

db.collection.ensureIndex({ <field>: < 1 or -1 > })

 

db.collection.createIndex( { "filed": sort } )

db.collection.createIndex( { "filed": sort , "filed2": sort } )

 

db.tab.ensureIndex({"id":1})

db.tab.ensureIndex({"id":1} ,{ name:"id_ind"})

db.tab.ensureIndex({"id":1,"name":1},{background:1,unique:1})

db.tab.ensureIndex( { "id" : "hashed" })

 

创建索引(两种方法)

 

 

filed :为键列

sort :为排序。1 为升序;-1为降序。

 

创建单列索引

创建索引并给定索引名称

后台创建唯一的复合索引

创建哈希索引

 (更多参数 看文章底部)

db.tab.indexStats( { index: "id_ind" } )

db.runCommand( { indexStats: "tab", index: "id_ind" } )

db.tab.getIndexes()

db.system.indexes.find()

(前2个似乎不能用,官方文档解释)

(not intended for production deployments)

查看索引

db.tab.totalIndexSize();

查看索引大小

db.tab.reIndex()

db.runCommand({reIndex:"tab"})

重建索引

db.tab.dropIndex(<indexname>)

db.tab.dropIndex("id_1")

db.tab.dropIndexes()

删除索引

<indexname>为getIndexes看到的索引名称

删除所有索引(注意!)

 

 



索引性能测试:

 

查看索引是否生效,分析查询性能有没有提高。先插入10万数据到集合tab

 

for(var i=0;1<=100000;i++){

var value=parseInt(i*Math.random());

db.tab.insert({"id":i,"name":"kk"+i,"value":value});

}

 

不知道是不是虚拟机的原因,插入了10分钟都未完成!~

自己又打开文件夹查看,一直进不去文件夹。结果客户端连接断开了!~查看服务竟然停了!


MongoDB 基础(三)mongodb 中的索引使用_Boo_03



重启服务,进去查看行数:96万!(过后再查看吧!就用这数据测试了!)

db.tab.find().count()



AnalyzeQuery Performance :​http://docs.mongodb.org/manual/tutorial/analyze-query-plan/​

分析函数

db.tab.find({"name":"kk50000"}).explain()

查询name=”kk50000”的执行分析

db.tab.find({"name":"kk50000"}).explain("queryPlanner")

db.tab.find({"name":"kk50000"}).explain("Verbosity")

db.tab.find({"name":"kk50000"}).explain("executionStats")

db.tab.find({"name":"kk50000"}).explain("allPlansExecution")

这3种方法执行结果完全包括上面这种的结果

db.tab.find({"name":"kk50000"}).explain()  结果做分析:

"cursor" : "BasicCursor",

"isMultiKey" : false,

"n" : 1,

"nscannedObjects" : 966423,

"nscanned" : 966423,

"nscannedObjectsAllPlans" : 966423,

"nscannedAllPlans" : 966423,

"scanAndOrder" : false,

"indexOnly" : false,

"nYields" : 7555,

"nChunkSkips" : 0,

"millis" : 4677,

"server" : "kk-ad:27017",

"filterSet" : false

游标类型。BasicCurso(扫描), BtreeCursor(索引)

是否多键(组合)索引

返回行数

扫描行数

扫描行数

所有计划扫描的次数

所有计划扫描的次数

是否在内存中排序

 

 

 

耗时(毫秒)

服务器

 



现在创建索引:

db.tab.createIndex({"name":1})


MongoDB 基础(三)mongodb 中的索引使用_默认值_04



db.tab.find({"name":"kk50000"}).explain() 使用索引的结果

"cursor" : "BtreeCursor name_1",

 "isMultiKey" : false,

 "n" : 1,

 "nscannedObjects" : 1,

 "nscanned" : 1,

 "nscannedObjectsAllPlans" : 1,

 "nscannedAllPlans" : 1,

 "scanAndOrder" : false,

 "indexOnly" : false,

 "nYields" : 0,

 "nChunkSkips" : 0,

 "millis" : 1,

 "indexBounds" : {

         "name" : [

                 [

                         "kk50000",

                         "kk50000"

                 ]

         ]

 },

 "server" : "kk-ad:27017",

 "filterSet" : false

游标使用索引BtreeCursor = name_1

 

 

 

 

 

 

 

 

 

 

耗时:1毫秒

 

 

 

 

 

 

 

 

 

 


上面可以看到,没使用索引时,耗时4677毫秒,使用索引后,1毫秒!~并且不用全文档扫描。




索引提示(hint),当前collection创建的索引:

db.tab.ensureIndex({"id":1} ,{name:"id_ind"})

db.tab.ensureIndex({"id":1,"name":1},{background:1,unique:1})

db.tab.ensureIndex( { "name" :"hashed" })



现在查询 id=5000 的行(结果集为1行)

db.tab.find({"id": 5000}).explain()


MongoDB 基础(三)mongodb 中的索引使用_字段_05



查询使用的是id和name的复合索引。

"nscannedObjectsAllPlans" : 2,

 "nscannedAllPlans" : 2,

 

现在加上索引提示,强制使用索引:

db.tab.find({"id": 5000}).hint({"id":1}).explain()


MongoDB 基础(三)mongodb 中的索引使用_默认值_06



这时使用的是单个键列为id的索引。

"nscannedObjectsAllPlans" : 1,

"nscannedAllPlans" : 1,

 

上面还可以看到,索引有个边界值“indexBounds”


MongoDB 基础(三)mongodb 中的索引使用_Boo_07



这个边界值在复合索引查询的时候,会导致扫描更多的数据。这是一个bug :​​wrong index ranges when using compound index on a list​



当然我们也可以自己限制边界值。

db.tab.find().min({"id":5000}).max({ "id":5005})


MongoDB 基础(三)mongodb 中的索引使用_字段_08



从上面看,实际只查询这个边界的内的数值。再查看执行计划:

db.tab.find().min({"id":5000}).max({ "id":5005}).explain()


MongoDB 基础(三)mongodb 中的索引使用_Boo_09



只是5行数据。如果查询id=5000的,但是索引边界又有问题,这时可以限制边界,如:

db.tab.find({"id": 5000 }).min({"id":5000}).max({ "id":5005})




在索引方法中,还有一个方法为cursor.snapshot(),它会确保查询不会多次返回相同的文档,即使是写操作在一个因为文档大小增长而移动的文档。但是,snapshot()不能保证插入或者删除的隔离性。snapshot()是使用在_id键列上的索引,因此snapshot()不能使用sort() 或 hint()。



分快照函数析snapshot()的查询结果:

db.tab.find({"id": 5000}).snapshot().explain()


MongoDB 基础(三)mongodb 中的索引使用_默认值_10


虽然使用了索引“_id”,但是把整个集合都搜索了!~

 

加索引提示看看,应该是报错的:

db.tab.find({"id": 5000}).snapshot().hint({"id":1})


MongoDB 基础(三)mongodb 中的索引使用_字段_11


果然是出错:snapshot 不能使用提示。




下面总结索引查询的一些方法:

Indexing Query Modifiers

db.tab.find({"id": 5000 }).hint({"id":1})

db.tab.find({"id": 5000 })._addSpecial("$hint",{"id":1})

db.tab.find({ $query: {"id": 5000 }, $hint: { "id":1 }})

使用键列id的索引查询id=5000的结果

db.tab.find({"id": 5000 }).snapshot()

db.tab.find({"id": 5000 })._addSpecial( "$snapshot", true )

db.tab.find({ $query: {"id": 5000 }, $snapshot: true })

使用快照的查询id=5000的结果

db.tab.find({"id": 5000 }).hint({"id":1}).explain()

db.tab.find({"id": 5000})._addSpecial("$explain",1)

db.tab.find({ $query: {"id": 5000 }, $hint: { "id":1 }, $explain: 1})

查看执行计划信息

索引边界设置

db.tab.find({"id": 5000 }).max({ "id":5005})

db.tab.find({ $query:{"id": 5000 },$max:{ "id": 5005}})

db.tab.find({"id": 5000 })._addSpecial("$max",{"id": 5005})

 

db.tab.find({"id": 5000 }).min({ "id":5000}).max({ "id":5005}).explain()

db.tab.find({ $query:{"id": 5000 },$max:{ "id": 5005},$min:{ "id": 5000}})

db.tab.find({"id": 5000 })._addSpecial("$min",{"id": 5000})._addSpecial("$max",{"id": 5005})



摘取了这了的一个总结:​​http://www.w3cschool.cc/mongodb/mongodb-indexing.html​

Parameter

Type

Description

background

Boolean

建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false

unique

Boolean

建立的索引是否唯一。指定为true创建唯一索引。默认值为false.

name

string

索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。

dropDups

Boolean

在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false.

sparse

Boolean

对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.

expireAfterSeconds

integer

指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。

v

index version

索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。

weights

document

索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。

default_language

string

对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语

language_override

string

对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.



​更多参考官方文档:Indexes​


标签:5000,MongoDB,db,find,索引,tab,mongodb,id
From: https://blog.51cto.com/hzc2012/6024076

相关文章

  • 自从学习了MongoDB高可用,慢慢的喜欢上了它,之前确实冷落了
    大家好,我是哪吒,最近项目在使用MongoDB作为图片和文档的存储数据库,为啥不直接存MySQL里,还要搭个MongoDB集群,麻不麻烦?让我们一起,一探究竟,继续学习MongoDB高可用和片键策略,实现......
  • 自从学习了MongoDB高可用,慢慢的喜欢上了它,之前确实冷落了
    大家好,我是哪吒,最近项目在使用MongoDB作为图片和文档的存储数据库,为啥不直接存MySQL里,还要搭个MongoDB集群,麻不麻烦?让我们一起,一探究竟,继续学习MongoDB高可用和片键策略,实......
  • 实战-mongodb副本集搭建以及整合springboot使用
    一mongodb介绍MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 Nosql技术门类redis内存型mongodb......
  • Day03 - 事务索引查询及PyMySQL
    1.将查询结果插入到另一张表中思考目前只有一个goods表,我们想要增加一个商品分类信息,比如:移动设备这个分类信息,只通过goods表无法完成商品分类的添加,那么如何实现添加......
  • MySQL 哈希索引、空间数据索引、全文索引
    1.哈希索引哈希索引基于哈希表实现,仅支持精确匹配索引所有列的查询。对于每行数据,存储引擎都会对所有的索引列计算出一个哈希码。哈希索引将所有的哈希码存储在索引中,同时保......
  • 如何高效高性能的选择使用 MySQL 索引?
    想要实现高性能的查询,正确的使用索引是基础。本小节通过多个实际应用场景,帮助大家理解如何高效地选择和使用索引。1.独立的列独立的列,是指索引列不能是表达式的一部分,也不......
  • MySQL索引使用注意事项
    数据库索引可以提高搜索效率,在创建数据库的时候,就要考虑到,针对哪个业务字段添加什么样的索引,可以提高数据的查询效率。所以,索引在数据库是有很重要的位置的。今天就来学习一......
  • 【Linux】Ubuntu镜像索引
    ✨Ubuntu镜像索引Ubuntu官方网站似乎UbuntuARM镜像并不容易寻找可以点击如下链接前往Ubuntu镜像索引选择需要版本http://cdimage.ubuntu.com/可以非常方便地下载到Des......
  • 【Linux】Kali Linux镜像索引
    ✨KaliLinux镜像索引通过分析KaliLinux下载链接不难发现如下镜像索引链接较新版本镜像:https://kali.download/base-images/较新版本虚拟机镜像:https://kali.downlo......
  • nginx索引静态文件
    前言针对nas服务器文件下载或者需要索引一些静态二进制文件的地方,可以利用nginx自带的索引文件功能实现。root/var/www/html;#索引目录autoindexon;autoindex_exact_......