mongodb 稀疏索引
稀疏索引(或者称间隙索引)就是只包含有索引字段的文档的条目,即使索引字段包含一个空值。也就是说间隙索引可以跳过那些索引键不存在的文档。因为他并非包含所有的文档,因此称为稀疏索引。与之相对的非稀疏索引或者说普通索引则包含所有的文档以及为那些不包含索引的字段存储null值。
一、间隙索引创建描述
稀疏索引(或者称间隙索引)就是只包含有索引字段的文档的条目,跳过索引键不存在的文档
本文中后面的描述使用间隙索引
创建索引的语法:
db.collection.createIndex(keys, options)
创建间隙索引示例:
db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
这个示例,哪些不包含xmpp_id的键(列)的文档将不会被索引
间隙索引不会被使用到的情形
如果一个间隙索引会导致查询或者排序操作得到一个不完整结果集的时候,MongoDB将不会使用这个索引,hint提示除外
哪些索引缺省情况就是间隙索引
2dsphere (version 2), 2d, geoHaystack, 文本索引等总是稀疏索引
间隙索引与唯一性
一个既包含稀疏又包含唯一的索引避免集合上存在一些重复值得文档,但是允许多个文档忽略该键。
二、间隙索引示例
1、创建间隙索引
> db.version()
3.2.10
> db.scores.insertMany([
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" },
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 },
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }])
//下面为score键创建稀疏索引
> db.scores.createIndex( { score: 1 } , { sparse: true } )
> db.scores.find( { score: { $lt: 90 } } )
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
//由于文档newbie并不包含score键,因此该文档不会出现在稀疏索引之中,也就不会被查询返回
> //下面查询socre小于90文档的执行计划
> db.scores.find( { score: { $lt: 90 } } ).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.scores", //Author : Leshami
"indexFilterSet" : false, //Blog : http://blog.csdn.net/leshami
"parsedQuery" : {
"score" : {
"$lt" : 90
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN", //使用到了索引扫描
"keyPattern" : {
"score" : 1
},
"indexName" : "score_1", //索引为score_1
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : true, //此处表名为间隙索引
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"score" : [
"[-inf.0, 90.0)"
...........
"ok" : 1
}
2、间隙索引无法使用的示例
> db.scores.find().sort( { score: -1 } )
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
//从上面的查询结果可知,基于索引列score的排序返回了所有的文档
//这个排序真实的执行计划则是全表扫描,因为索引键并不包含不存在的用户id为newbie的文档
> db.scores.find().sort( { score: -1 } ).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.scores",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [ ]
},
"winningPlan" : {
"stage" : "SORT",
"sortPattern" : {
"score" : -1
},
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "COLLSCAN", //使用了集合扫描方式
"filter" : {
"$and" : [ ]
},
"direction" : "forward"
}
............
"ok" : 1
}
3、强制间隙索引的示例
//如果我们强制增加一个hint提示,则用户id为newbie的文档未被返回,即走了索引(执行计划此处略)
> db.scores.find().sort( { score: -1 } ).hint( { score: 1 } )
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
4、间隙索引与唯一约束
在唯一索引中,唯一索引会把null当做值,也就是说为null的通常只能有一个。后面的null将无法插入。
//下面创建一个带有唯一约束的稀疏索引
> db.scores.createIndex( { score: 1 } , { sparse: true, unique: true } )
{
"ok" : 0,
"errmsg" : "Index with name: score_1 already exists with different options",
"code" : 85
}
//由于score列上已经存在一个索引了,因此提示我们,需要先删除,再创建
> db.scores.dropIndex("score_1")
{ "nIndexesWas" : 2, "ok" : 1 }
> db.scores.createIndex( { score: 1 } , { sparse: true, unique: true } )
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
//下面尝试插入一些带有score键以及不带有score键的文档,如下,可以成功插入
> db.scores.insert( { "userid": "AAAAAAA", "score": 43 } )
WriteResult({ "nInserted" : 1 })
> db.scores.insert( { "userid": "CCCCCCC" } )
WriteResult({ "nInserted" : 1 })
//下面插入一些score相关的文档,提示重复,如下示例
> db.scores.insert( { "userid": "AAAAAAA", "score": 82 } )
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.scores index: score_1 dup key: { : 82.0 }"
}
})
> db.scores.insert( { "userid": "BBBBBBB", "score": 90 } )
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.scores index: score_1 dup key: { : 90.0 }"
}
})
三、小结
a、间隙索引就是创建索引的索引列在某些文档上列不存在,导致索引存在间隙。
b、间隙索引在创建时应指定选项:{ sparse: true }
c、间隙索引列上可以指定唯一性约束
参见:http://blog.csdn.net/leshami/article/details/53897157
mongodb 稀疏索引的更多相关文章
- MongoDB的索引(三)
MongoDB的索引: 1. _id索引 该索引是大多数集合默认创建的索引,也就是说用户每插入一个数据,MongoDB会自动生成一条唯一的_id字段. 2. 单键索引 单键索引是最普通的索引,它不会自 ...
- MongoDB数据库索引
前面的话 索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录.这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查 ...
- 五、MongoDB的索引
一.MongoDB的下载.安装与部署 二.MongoDB的基础知识简介 三.MongoDB的创建.更新和删除 四.MongoDB的查询 五.MongoDB的索引 1.简介 它就像是一本书的目录,如果没 ...
- mongodb 的索引
索引加快了查询速度,但是降低了写入速度.所以不要在没必要的属性上加索引. 在 mongodb 中索引可以按倒序/正序创建,便于排序. ...
- 快速掌握mongoDB(三)——mongoDB的索引详解
1 mongoDB索引的管理 本节介绍mongoDB中的索引,熟悉mysql/sqlserver等关系型数据库的小伙伴应该都知道索引对优化数据查询的重要性.我们先简单了解一下索引:索引的本质就是一个排 ...
- mongodb的索引原理
首先说一下为什么要有索引,大家都知道mongdb是非关系型文档类型数据库,用过的人都有同一种感受,查询的效率太低,当你想提高查询效率的时候可以就需要使用索引了. 哈哈,本来想写一篇的,在网上看到了一篇 ...
- mongodb添加索引
mongodb可以添加多列索引 稠密索引:该列中即使有null值也能给你查出来 稀疏索引:该列中查不出包含null值的列 二叉树索引是由码放的顺序的,哈希则是散列,相邻的数字,排列顺序并不一定紧邻
- mongodb的索引操作
在mongodb中,当我们一个集合中的数据量非常大时,比如几百万条数据,如果不使用索引,对数据的查询就会进行全表扫描,这个时候查询的速度就会非常的慢,此时我们就需要为集合建立上索引,从而加快查询的速度 ...
- MongoDB 覆盖索引查询
MongoDB 覆盖索引查询 官方的MongoDB的文档中说明,覆盖查询是以下的查询: 所有的查询字段是索引的一部分 所有的查询返回字段在同一个索引中 由于所有出现在查询中的字段是索引的一部分, Mo ...
随机推荐
- R语言预测实战(第一章)
本例使用forecast包中自带的数据集wineind,它表示从1980年1月到1994年8月, 由葡萄酒生产商销售的容量不到1升的澳大利亚酒的总量.数据示意如下: #观察曲线簇 len=1993-1 ...
- 用三目运算,与if判断 函数调用 达到相同判定作用
三目运算符: 操作数1 ? 操作数2 : 操作数3 (操作数1位bool类型,操作数2和操作数3为两个相同的任何类型) 返回结果:如果操作数1判定结果为真,则将操作数2作为返回结果如果操作 ...
- php7新特性的理解和比较
1. null合并运算符(??) ??语法: 如果变量存在且值不为NULL,它就会返回自身的值,否则返回它的第二个操作数. //php7以前 if判断 if(empty($_GET['param']) ...
- python使用中遇到的一些问题
一./usr/bin/ld:cannot find -lxxx错误 例如出现了问题: /usr/bin/ld:cannot find -lssl 其中xxx表示函式库文件名称,如上面的libssl.s ...
- 【SpringBoot】 Java中如何封装Http请求,以及JSON多层嵌套解析
前言 本文中的内容其实严格来说不算springboot里面的特性,属于JAVA基础,只是我在项目中遇到了,特归纳总结一下. HTTP请求封装 目前JAVA对于HTTP封装主要有三种方式: 1. JAV ...
- python通过post提交数据的方法
python通过post提交数据的方法 本文实例讲述了python通过post提交数据的方法.分享给大家供大家参考. 具体实现方法如下: # -*- coding: cp936 -*- imp ...
- memcpy复制字符串的注意事项/memcpy不能用来拷贝类类型
strcpy复制src到dst,最后将dst的下一个位置置为'\0',所以dst是以'\0'结尾的字符串 ] = "abcde"; cout << c1 << ...
- 浮点数float累加误差解决方式总结
首先是float累加产生误差的原因,该部分转自:http://blog.csdn.net/zhrh0096/article/details/38589067 1. 浮点数IEEE 754表示方法 要 ...
- [LeetCode] 421. Maximum XOR of Two Numbers in an Array(位操作)
传送门 Description Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Fin ...
- redis可以做什么?
redis可以做什么? 1.缓存,毫无疑问这是Redis当今最为人熟知的使用场景.在提升服务器性能方面非常有效: 2.排行榜,如果使用传统的关系型数据库来做这个事儿,非常的麻烦,而利用Redis的So ...