mongodb学习(三)-mongodb索引
2017-12-31 15:11
351 查看
3.mongodb索引
@(mongodb)mongodb索引
格式
基本操作
索引分类
_id索引
单键索引
多键索引
复合索引
过期索引
全文索引
全文索引建立
使用全文索引
全文索引的相似度
全文索引的限制
地理位置索引
2d索引
geoNear查询
2dsphere索引
索引分析
mongostat
profile
mongodb日志
explain
在数据量特别大(几百万)的情况下,如果没有建立索引,那么对于没有建立索引的字段进行查询将不会返回任何数据,因此建立索引是十分重要的
格式
db.COLLECTION_NAME.ensureIndex({KEY:1},{Parameter:value})
Parameter | Type | Description |
---|---|---|
background | Boolean | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 “background” 可选参数。 4000 “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. |
db.values.ensureIndex({open: 1, close: 1}, {background: true})在后台创建索引
db.collenction.ensureIndex({x:1,y:2,z:3},{name="normal_index"})//指定名字
db.collenction.dropIndex("normal_index")可用名字代替删除索引
db.collenction.ensureIndex(({m:1,n:1}, {unique: true/false})唯一索引,这里注意,如果是已经有了记录的表,可能会报错“E11000 duplicate key error collection: test.collenctionindex: m_1_n_1 dup key: { : null, : null }”原因是在你建立m:1,n:1的复合索引时,之前存在的多笔数据都没有m和n的字段,也就代表每一笔没有m和n字段的数据都是索引m:null,n:null的情形,而此时你又指定该复合索引为unique,立刻报索引重复错误!
db.collenction.ensureIndex({title : 1}, {sparse : true})稀疏索引,mongo的默认模式是密集索引,在稀疏索引的情况下,如果某个对象没有索引的属性,将不会建立一个
{title:null}的索引,可加快插入的速度。和unique结合可以达成唯一插入,有则建索引,无则不建索引的效果,就不会出现上面提到的unique索引报错的情况
基本操作
db.test_collection.getIndexes()//查看集合的索引情况
db.test_collection.ensureIndex({x:1})//创建索引,key代表字段名,value值代表方向,1代表正向排序,-1 代表负向排序
如果数据量非常大,创建索引需要消耗一定的时间,创建索引的时候需要注意时机,如果已经有大量数据了,这个时候创建索引会严重影响数据库的性能,
应该在创建数据表的时候就创建索引,索引是在插入数据之后创建的,所以,对插入数据有稍微的影响,不过对于提高的查询效率而言是值得的
索引分类
_id索引
_id索引是绝大多数集合默认建立的 索引。对于每个插入的数据,MongoDB都会自动生成一条唯一的_id字段。
单键索引
单键索引是最普通的索引,单键索引不会自动创建db.test_collection.ensureIndex({x:1})//创建单键索引
多键索引
当为一个字段插入的数据是一个数组(集合等表示多条数据就行)时,MongoDB为对应的值,默认创建了一个多键索引db.test_collections.insert({x:[1,2,3,4]})插入一个数组
> db.test_collections.find({x:4}) { "_id" : ObjectId("5a44f99ca3fe201251392183"), "x" : [ 1, 2, 3, 4 ] }
直接就可以通过数组中的值查出来了
复合索引
db.collection.ensureIndex({x:1,y:2})
过期索引
又称 TTL(Time To Live,生存时间)索引,即在一段时间后会过期的索引(如登录信息、日志等)过期后的索引会连同文档一起删除
存储在过期索引字段的值必须是指定的时间类型
说明:必须是ISOData或者ISOData数组,不能使用时间戳
如果指定的是ISOData数组,则按照数组中最小的数值计算删除
过期期索引不能是复合索引,只能是单键索引
删除时间不是精确
说明:删除过程是由后台程序每60s跑一次,而且删除也需要一些时间
db.local_2.ensureIndex({time:1},{expireAfterSeconds:30}) db.local_2.insert({time:new Date()}) db.local_2.find()
全文索引
全文索引建立
在MongoDB中每个数据集合只能创建一个全文索引, 所以使用全文索引进行查询时不会起冲突db.articles.ensureIndex({key:"text"})//单值索引的value是 1或者 -1代表正向或者你向,而全文索引的value则是固定的字符串”text”
db.articles.ensureIndex({key1:"text",key2:"text",key3:"text"})//多字段
db.articles.ensureIndex({"$**":"text"})//为表的所有字段创建全文索引
使用全文索引
db.articles.find({$text:{$search:"coffee"}})
db.articles.find({$text:{$search:"aa bb cc"}})包含aa或bb或cc的数据
db.articles.find({$text:{$search:"aa bb -cc"}})包含aa或者bb,但是不包含cc的数据
db.articles.find({$text:{$search:"\"aa\" \"bb\" \"cc\""}})同时包含aa、bb、cc的数据(用“”包裹起来,引号需要用反斜杠转义)
全文索引的相似度
$meta操作符:
{score:{$meta:"textScore"}}
写在查询条件之后可以返回返回结果的相似度,
textScore为固定字符串
与 sort 一起使用可以达到很好的使用效果
db.imooc_2.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}})
db.imooc_2.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}});根据score字段排序
实际查询之后会见到如下所示的效果
> db.test_collection.find({$text:{$search:"aa"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}}) { "_id" : ObjectId("5a45f28022d4795f1452d9bf"), "article" : "aa", "score" : 1.1 } { "_id" : ObjectId("5a45f11522d4795f1452d9bb"), "article" : "aa bb cc dd", "score" : 0.625 } { "_id" : ObjectId("5a45f1a222d4795f1452d9bd"), "article" : "aa bb ii gg", "score" : 0.625 } { "_id" : ObjectId("5a45f1b422d4795f1452d9be"), "article" : "aa bb zz yy", "score" : 0.625 } { "_id" : ObjectId("5a45f19b22d4795f1452d9bc"), "article" : "aa bb cc ff hh", "score" : 0.6 }
全文索引的限制:
每次查询,只能指定一个$text查询
$text查询不能出现在
$nor查询中
查询中如果包含了
$text,
hint不再起作用
MongoDB全文索引在3.2版本之前还不支持中文
地理位置索引
概念:将一些点的位置存储在MongoDB中,创建索引后,可以按照位置来查找其他点子分类:
- 2d索引:用于存储和查找平面上的点
db.集合名.ensureIndex({w:"2d"})
- 2dsphere索引:用于存储和查找球面上的点
db.集合名.ensureIndex({w:"2dsphere"})
位置表示方式:经纬度[精度,纬度]
取值范围:精度[-180,180],纬度[-90,90]。如果超出范围会出现意想不到的错误
查找方法:
- 查找据李某个点一定距离内的点
- 查找包含在某区域内的点
2d索引
2d索引:db.集合名.ensureIndex({w:"2d"})
例子: db.集合名.find({w:{$near:[1,1]}})
db.collection.find({w:{$near:[1,1], $maxDistance:10}})查找距离[1,1]最大距离为10的点,3.2版本后可以使用minDistance
db.collection.find({w:{$geoWithin:{$box:[[0,0],[3,3]]}}})查找在矩形[0,0] [3,3]范围内的点
db.collection.find({w:{$geoWithin:{$center:[[0,0],5]}}})查找以[0,0]为圆心半径为5的圆内的点
db.collection.find({w:{$geoWithin:{$polygon:[[0,0],[1,1],[4,5],[6,6]]}}})查找以[0,0],[1,1],[4,5],[6,6]为多边形内的点
想不明白的在脑子里假想一个坐标系,就很好理解了
geoNear查询:
除了使用 find的方式之外,还可以使用runCommand来执行语句db.runCommand({ geoNear:"集合名", near:[x, y], minDistance: (对2d索引无效) maxDistance: num:(返回的数量)
{ "results":[ //查询的结果 { "dis": //查找到的数据与所指定查找的数据之间的距离 "obj":{} //查找到的数据 } ], "stats":{ //查询的参数 "nscanned": //扫描了哪些数据 "objectsloaded": "avgDistance": //平均距离 "maxDistance": //最大的距离 "time": //花费的时间 }, "ok": }
2dsphere索引
2dsphere索引:db.集合名.ensureIndex({w:"2dsphere"})
2Dsphere位置表示方式:
GeoJSON:描述一个点,一条直线,多边形等形状。
格式:
{type:”, coordinates:[list]}
GeoJSON查询可支持多边形交叉点等,支持MaxDistance 和 MinDistance
详细请看
基于MongoDB 2dSphere索引查找最近的点
索引分析
创建索引的好处:加快索引查询。创建索引的坏处:增加磁盘消耗,降低写入性能。
索引分析的工具
- mongostat工具
- profile集合介绍
- 日志
- explain分析
mongostat
mongostat是mongodb自带的用来查看mongodb运行状态的一个工具使用方法:
./mongostat -h ip:port -u -p
字段说明:
返回的采样数据采用百分比
索引情况:idx miss 索引未命中率
输出字段:
inserts –当前的插入数量(单位:秒)
query –当前的查询数量(单位:秒)
update –当前更新的数量(单位:秒)
delete –当前的删除数量(单位:秒)
getmore –当前的迭代返回数量(单位:秒)
command –执行命令的数量
flushes –刷盘时间(单位:秒)
mapped –mmap 大小
vsize –磁盘空间大小
res –常驻内存大小
faults –内存换页时间(单位:秒)
locked –锁的使用情况
idx miss –未命中索引率
qr|qw –读|写队列
ar|aw –活跃的客户端连接数量
netIn –网卡输入流量
netOup –网卡输
a671
出流量
conn –当前连接到mongodb的连接数量
inserts/query/update/delete: 分别指当前mongodb插入、查询、更新、删除 数量,以每秒计;
getmore: MongoDB返回结果时,每次只会返回一定量;当我们继续用find()查询更多数据时,系统就会自动用getmore来获取之后的数据;
command: 执行的命令数量;
flushes: MongoDB使用虚拟内存映射的方式管理数据,我们在向MongoDB写入或查询数据时,MongoDB会做一次虚拟内存映射,有些数据其实是在硬盘上的;每隔一段时间,MongoDB会把我们写到内存的数据flush到硬盘上;这个数据大的话,会导致mongodb的性能较差;
mapped/vsize/res: 与磁盘空间大小有关,申请的内存大小;
faults:如果我们查询的数据,没有提前被MongoDB加载到内存中,我们就必须到硬盘上读取,叫做“换页”;如果faults比较高,也会造成性能下降;
idx miss: 表示我们的查询没有命中索引的比率;如果很高,说明索引构建有问题,索引不合适或者索引数量不够;
qr|qw: 说明MongoDB的写队列或者读队列的情况。我们向MongoDB读写时,这些请求会被放到队列中等待。数量大(几百上千)说明MongoDB处理速度慢或者读写请求太多,性能会下降。
ar|aw: 当前活跃的读写客户端的个数。
qr/qw 表示读队列和写队列值,较高时数据库的性能会很明显的下降
idx miss 表示查询时索引命中情况,较高时影响查询效率
profile
db.getProfilingStatus()
{ “was” : 0, “slowms” : 100 }
查看当前数据库的记录级别
db.getProfilingLevel()
0|1|2
设置当前数据库的profile记录级别
db.setProfilingLevel(0|1|2)
was –profile记录级别,0关闭,1记录所有超过slowms阈值的慢查询,2记录所有操作
slowms –慢查询阀值
查看profile文件
db.system.profile.find()
db.system.profile.find().sort({$natural:-1}).limit(1)查询profile集合的内容,自然排序,限制只显示一条日志
{ "op" : "query",--操作类型 "ns" : "imooc.system.profile", --查询的命名空间,;databasename.collectionname' "query" : { "query" : { }, --查询条件 "orderby" : { "$natural" : -1 } }, --约束条件 "ntoreturn" : 1, --返回数据条目 "ntoskip" : 0, --跳过的条目 "nscanned" : 1, --扫描的数目含索引 "nscannedObjects" : 1, --扫描的数据数目 "keyUpdates" : 0, -- "numYield" : 0, --其他情况 "lockStats" : { --锁状态 "timeLockedMicros" : { --锁占用时间(毫秒) "r" : NumberLong(82), --读锁 "w" : NumberLong(0) --写锁 }, "timeAcquiringMicros" : { "r" : NumberLong(2), "w" : NumberLong(2) } }, "nreturned" : 1, "responseLength" : 651, --返回长度 "millis" : 0, --查询时间
注意:如果开启了profile的功能,并且此时profile记录的数据比较大,系统的消耗是比较大的,所以,这个工具最好在上线之前的测试时开启此功能,用来查看数据库的设计和应用程序的设计,上线的系统是不建议使用此方法的,因为系统的开销比较大!
mongodb日志
就是log目录下的那个日志berbose = vvvvv 日志记录级别,1-5个v,越多越详细
explain
db.colltction.find({x:1}).explain(){
“cursor” : “BasicCursor”, –使用的游标
“isMultiKey” : false,
“n” : 1,
“nscannedObjects” : 100000, –扫描的数据量
“nscanned” : 100000, –包含索引的扫描量
“nscannedObjectsAllPlans” : 100000,
“nscannedAllPlans” : 100000,
“scanAndOrder” : false,
“indexOnly” : false,
“nYields” : 781,
“nChunkSkips” : 0,
“millis” : 25, –查询消耗时间(毫秒)
“server” : “XXX”,
“filterSet” : false
}
相关文章推荐
- MongoDB学习 索引
- MongoDB的学习--索引
- 学习MongoDB--(5-2):索引(查看索引的使用,管理索引)
- 菜鸟的mongoDB学习---(六)MongoDB 索引
- node学习(9)-- mongodb索引和explain
- 【MongoDB学习笔记27】MongoDB的TTL索引
- MongoDB学习 索引
- mongoDB学习(三)--索引操作
- mongodb学习:mongodb索引原理
- mongodb 学习笔记 04 -- 游标、索引
- MongoDB学习 索引
- MongoDB的学习--索引类型和属性(转)
- 《MongoDB权威指南》学习整理----MongoDB中的索引
- 8天学习MongoDB——第四天 索引操作
- 【MongoDB学习笔记25】MongoDB的索引类型
- MongoDB基础学习二----MongoDB中常用的索引操作
- MongoDB学习 索引
- Mongodb的索引--学习笔记(未完)
- 【MongoDB学习笔记22】MongoDB的索引管理
- MongoDB学习 索引