MongoDB权威指南

MongoDB权威指南
5章-索引
5.1-索引简介
5.1.0-简介
不使用索引的查询称为全表扫描
explain结果集
nscanned=查询扫描的文档总数
millis=查询耗费的毫秒数
n=查询结果的数量
创建索引=db.users.ensureIndex({“username”:1})
db.currentOp()查看索引创建进度
每个集合最多只能有64个索引
5.1.1-复合索引简介
复合索引就是建立在多个字段上的索引
ensureIndex({“age”:1,”username”:1})
[0,”user100309”]->0x0c965148
每个索引包含age和username字段,并指向文档在磁盘的位置
多值查询
db.users.find({“age”:{“ gte":21," lte”:30}})
如果结果集>32MB,mongoDB会报错,拒绝排序
db.users.find({“age”:{“ gte":21," lte”:30}}).sort({“username”:1})
explain
cursor:此次查询所使用的索引
scanAndOrder=true:MongoDB必须在内存中对数据进行排序
hint:强制使用某个索引
索引本质上是树,最小的值在最左边的叶子上,最大的值在最右边的叶子上
应该尽可能让索引右平衡,ex:_id索引
5.1.2-使用复合索引
选择键的方向
相互反转(在每个方向*-1)的索引是等价的
只有在基于多键排序时,键的方向才变得重要
使用覆盖索引
当一个索引包含用户请求的所有字段,可以认为这个索引覆盖了本次查询
在覆盖索引上执行explain,‘indexOnly’=true
隐式索引
一个拥有N个键的索引,可以同时得到所有这N个键的前缀组成的索引
5.1.3- 使1x:$exists:falsenull,null使 exists”
2-范围
db.users.find({“age”:47,”username”:{“ gt":"user5"," lt”:”user8”}})
3-OR查询
OR可以对每个子句都使用索引,OR实际上是执行两次查询然后合并结果
db.foo.find(“ or:[x:123,y:456])使in5.1.41db.users.ensureIndex(loc.city:1)2db.blog.ensureIndex(comments.date:1),3,explain()isMultikey=true5.1.5,,,.5.2explainhintnscanned:使,n:nscannedObjects:scanAndOrder:indexOnly:nYields:indexBounds:,使,.,.,1000,.5.3hint(natural:1)5.4db.users.ensureIndex(username:1,unique:1),null<1024dropDups,,.ensureIndex(username:1,unique:true,dropDups:true),dropDupssparse,ex:email,,..ensureIndex(email:1,unique:true,sparse:true)5.5system.indexes,.ensureIndexdropIndexesdb.collectionName.getIndexes:ensureIndex(a:1,b:1,name:)55.15.1.0使explainnscanned=millis=n==db.users.ensureIndex(username:1)db.currentOp()645.1.1ensureIndex(age:1,username:1)[0,user100309]>0x0c965148ageusername,db.users.find(age:$gte":21,"$lte:30)>32MB,mongoDBdb.users.find(age:$gte":21,"$lte:30).sort(username:1)explaincursor:使scanAndOrder=true:MongoDBhint:使,,ex:id5.1.2使(1)使explain,indexOnly=trueNN5.1.3 操作符如何使用索引
1-低效率的操作符
{“x”:{“exists”:false}}  
                    索引中,不存在的字段和null的存储方式是一样的,查询必须遍历检查这个值是null还是不存在  
                稀疏索引  
                    不能使用“
exists”
2-范围
db.users.find({“age”:47,”username”:{“ gt":"user5"," lt”:”user8”}})
3-OR查询
OR可以对每个子句都使用索引,OR实际上是执行两次查询然后合并结果
db.foo.find(“$or”:[{“x”:123},{“y”:456}])
使用in查询是无法控制返回文档的顺序
5.1.4-索引图像和数组
1-索引嵌套文档
db.users.ensureIndex(“loc.city”:1)
对整个子文档建立索引只会提高整个子文档的查询速度
2-索引数组
db.blog.ensureIndex(“comments.date”:1)
对数组建立索引实际是是对数组的每个元素建立索引,而不是对数组本身建立索引
3-多键索引
如果某个索引的键在文档中是个数组,那这个索引会被标记为多键索引
explain()的isMultikey=true
5.1.5-索引基数
基数就是集合中某个字段拥有的不同值得数量
通常一个字段的基数越高,这个键上的索引就越有用
一般来说,应该在基数较高的字段上建立索引,或者至少把基数较高的键放在复合索引的前面.
5.2-explain和hint
查询优化器
nscanned:如果有使用索引,那么这个数字就是查找过的索引条目数量
n:本次查询返回的文档数量
nscannedObjects:按照索引指针去磁盘上查找实际文档的次数
scanAndOrder:是否在内存中对结果进行了排序
indexOnly:是否只用索引就能完成本次查询
nYields:本次查询暂停的次数
indexBounds:索引的遍历范围
这个查询计划会被缓存,这个查询接下来都会使用它,直到集合数据发生了比较大的变化.如果在最初的计划评估之后集合发生了比较大的变化,查询优化器会重新挑选可行的查询计划.建立索引时,或是每执行1000次后查询后,查询优化器会重新评估查询计划.
5.3-何时不该用索引
可以用hint({“natural”:1})强制数据库做全表扫描
5.4-索引类型
唯一索引
确保集合的每一个文档的指定键都有唯一值
db.users.ensureIndex({“username”:1},{“unique”:1})
如果一个文档没有对应的键,索引会将其作为null存储
所有的字段都必须<1024字节才能被包含到索引里
复合唯一索引
去除重复
dropDups,如果遇到重复的值,第一个会被保留,之后的重复文档都会被删除
.ensureIndex({“username”:1},{“unique”:true,”dropDups”:true})
对于比较重要的数据,千万不要用dropDups
稀疏索引
sparse可以创建稀疏索引,ex:如果有一个可选的email字段,但是如果提供了这个字段,那么它的值必须是唯一的.
.ensureIndex({“email”:1},{“unique”:true,”sparse”:true})
5.5-索引管理
标识索引
重复创建相同的索引是没有任何作用的
system.indexes是一个保留集合,不能在其中插入或删除文档.只能通过ensureIndex或dropIndexes对其进行操作
db.collectionName.getIndexes查看指定集合上的索引信息
标识索引:ensureIndex({“a”:1,”b”:1},{“name”:”索引名”})
修改索引
DISSIDIA思维导图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值