一、索引的创建和使用
1.1 索引创建和删除:
创建索引时的格式:db.collection.ensureIndex({param}, {param})
其中,第二个参数是索引的属性。
索引属性:
比较重要的属性有:
-
名字:
db.collection.ensureIndex({}, {name, ""})
说明:默认索引名字是“字段名_类型”,名字可以进行自定义设置 -
唯一性:
db.collection.ensureIndex({}, {unique, true/false})
db.testIndex.ensureIndex({a:1,b:1}, {unique: true})
保证唯一性,类似于设定 a 字段与 b 字段为联合主键
-
稀疏性:
db.collection.ensureIndex({}, {sparse, true/false})
mongodb 默认创建的索引都是不稀疏的
用于对某些不存在建立索引字段的数据元素,不对其建立索引。减少索引占用的空间,提高插入速度。 -
是否定时删除:
db.collection.ensureIndex({}, {expireAfterSeconds: })
,具体查看过期索引
删除索引可以通过其索引名进行:db.user_collection.dropIndex("testIndexName")
1.2 索引种类:
1.2.1 _id 索引。
_id 索引是绝大多数集合默认建立的索引。
对于每个插入的数据,MongoDB 都会自动生成一条唯一的_id 字段。
1.2.2 单键索引。
单键索引是最普通的索引。
与_id 索引不同,单键索引不会自动创建。
db.user_collection.ensureIndex({x:1}) //创建索引,为1正向排序,为-1逆向排序
1.2.3 多键索引。
与单键索引创建形式相同,区别在于字段的值。
单键索引:值为一个单一的值,例如字符串,数字或日期。
多键索引:值具有多个记录,例如数组。
1.2.4 复合索引。
查询条件不只有一个时,就需要建立复合索引。
db.testCollection.ensureIndex({x:1,y:1})
1.2.5 过期索引。
是在一段时间后会过期的索引。
在索引过期后,相应的数据会被删除。
适合存储一些在一段时间之后会失效的数据比如用户的登录信息、存储的日志。
存储在过期索引字段的值必须是指定的时间类型。必须是 ISODate 或者 ISODate 数组,不能使用时间戳,否则不能被自动删除。
若是 ISODate 数组,则按照最小的时间进行删除。
过期索引不能是复合索引。
删除时间不精确,因删除过程是由后台程序每 60s 跑一次,且删除需要时间,故存在误差。
db.user_collection.ensureIndex({time:1}, {expireAfterSeconds:30}) //设定过期索引。
db.user_collection.insert({time: new Date()}) //此条数据因过期索引的设置,在30s后会被删除。(有误差)
db.user_collection.insert({time:1}) //此条数据不会受过期索引的影响被删除。因为该字段的值不是指定的时间类型。
1.2.6 全文索引。
对字符串与字符串数组创建全文可搜索的索引。
对单个字段建立索引:db.articles.ensureIndex({key:”text”});
对多个字段建立索引:db.articles.ensureIndex({key_1:”text”, key_2:”text”});
对所有字段建立索引:db.articles.ensureIndex({“$**”:”text”});
使用:
搜索关键字 coffee :
db.articles.find({$text:{$search:”coffee”}});
或查询,搜索关键字 aa 或 bb 或 cc :
db.articles.find({$text:{$search:”aa bb cc”}});
-表示排除,搜索包含关键字 aa 或 bb,并不包含 cc :
db.articles.find({$text:{$search:”aa bb -cc”}});
加引号,表示并且,搜索包含 bb 或包含 cc 或两个都不包含,并且包含 aa 的:
db.articles.find({$text:{$search:”\“aa\” bb cc”}});
表示包含 aa 且包含 bb 且包含 cc 的:
db.articles.find({$text:{$search:"\"aa\" \"bb\" \"cc\""}})
全文索引相似度:$meta操作符:{score: {$meta: “textScore”}}
写在查询条件后面可以返回结果的相似度,与 sort 一起使用,可以达到很好的实用效果。
db.articles.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}})
db.articles.find({$text:{$search:"aa bb"}}, {score: {$meta: "textScore"}}).sort({score: {$meta: "textScore"}})
全文索引使用限制:
- 每次查询,只能指定一个 $text 查询。
- text查询不能出现在nor 查询中。
- 查询中如果包含了 $text,hint(指定使用某索引)不再起作用。
- 全文索引不支持中文。
1.2.7 地理位置索引。
将一些点的位置存储在 MongoDB 中,创建索引后,可以按照位置来查找其他点。
子分类:
2d 索引,用于存储和查找平面上的点。
2dsphere,用于存储和查找球面上的点。
一般查找方式有两种:
- 查找以某点为中心点,一定距离内的点。
- 查找包含在某区域内的点。
一般可以用在打车、电商查找一定范围内的商家等方面。也可用于查找一定范围内的项目等。
2d 索引:
创建方式:
db.collection.ensureIndex({w:”2d”})
位置表示方式:[经度,纬度]
取值范围:经度[-180, 180],纬度[-90, 90]
查找方式:
-
查找以某点为中心点,一定距离内的点。
a. $near 查询查询距离某个点最近的点。
db.location.find({w:{$near: [1,1]}}) 默认选中前100个 db.location.find({w:{$near: [1,1], $maxDistance:10}})
有maxDistance,但没有minDistance
b. geoNear 查询
$box:矩形使用
表示方式:{$box:[[,], [,]]}
$center:圆形使用
表示方式:{$center:[[,], r]}
$polygon:多边形使用
表示方式:{$polygon:[[,],[,],[,]]}db.location.find({w:{$geoWithin: {$box: [[0,0],[3,1]]}}}) //查询在[0,0]~[3,1]的矩形内的点 db.location.find({w:{$geoWithin: {$center: [[0,0],3]}}}) //查询在以[0,0]为圆心,半径为3的圆形内的点 db.location.find({w:{$geoWithin: {$polygon: [[0,0],[0,1],[1.1,1.1]]}}}) //查询在多边形内的点
-
查找包含在某区域内的点。
a. $geoWithin 查询
db.runCommand({geoNear:, near: [x,y], minDistance, (对2d索引无效) maxDistance, num: })
查询结果中,stats 中:
time—花费的时间
maxDistance—最大距离
avgDistance—平均距离
results 中:
dis—该点距离所选点的距离
obj—查找到的文档
2dsphere 索引:
球面地理位置索引
创建方式:
db.collection.ensureIndex({w:”2dsphere”})
二、索引构建情况分析
索引好处:加快索引相关的查询。
索引坏处:增加磁盘空间消耗,降低写入性能。
2.1 mongostat 工具介绍
输入命令:
mongostat –h 127.0.0.1:12345
显示结果如下:
实际反映性能最直观的是 qr|qw,读队列和写队列,若对应的值比较高,则说明有比较严重的性能问题。
idx miss% 表示查询没有应用索引的情况,若数据量较小,不太看得出来。若 idx miss% 较高,很容易导致 qr 较高。
2.2 profile 集合介绍
开启 profile 会记录下操作的详情。可用于分析操作。
查看当前 profile 级别:
db.getProfilingStatus()
得到结果如下:
{“was”: 0, “slowms”: 100}
profile level 有 3 个级别(was 属性):
0--profile 是关闭的,不会记录任何操作。
1--以 slowms(毫秒数)为阀值,会记录超过 slowms 的操作。
2--会记录任何操作。
设置 profile 级别:
db.setProfilingLevel(2)
profile 会记录在 system.profile
中:
查询 system.profile
中最近一条记录:
db.system.profile.find().sort({$natural: -1}).limit(1)
结果示例如下图:
op—操作类型
ns—命名空间,数据库名.集合名
query—find 的字符串
orderby—sort 的条件
cursorid—多次 getmore 是保存的游标
ntoreturn—返回的数据条数
ntoskip—跳过的数据数目
nscanned—扫描的索引/实体数目
nscannedObjects—扫描的实体数目,一般 nscanned>=nscannedObjects
timeLockedMicros—锁的占用情况(单位:微秒)
profile 的开启会记录每次操作的详情,故会影响 mongodb 的使用性能,所以 profile 的使用场景多是新系统上线前的测试阶段。
2.3 日志介绍
配置 mongo.conf
文件:
添加属性 verbose=vvvvv
通过使用 verbose 控制日志详细程度,分 1~5 个 v,v 越多,详细度越高。
2.4 explain 分析
可以使用 explain
查看操作详情。可以用来查看特定索引的使用情况。
如:
db.users.find().explain()
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于