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 ...
随机推荐
- OC + RAC (九) 过滤
// 跳跃 : 如下,skip传入2 跳过前面两个值 // 实际用处: 在实际开发中比如 后台返回的数据前面几个没用,我们想跳跃过去,便可以用skip - (void)skip { RACSubjec ...
- 【HDOJ6641】TDL(数论)
题意:定义f(n,m)是第m小的数字x,使得x>n且gcd(x,n)=1 已知 求最小的n使得 k<=1e18,m<=1e2 思路: #include<bits/stdc++. ...
- 整数解 (hdu 2092
整数解 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- Visual Studio Code - 快捷键
默认快捷键 Visual Studio Code 默认快捷键 代码提示(自动补全,自动完成) 默认是快捷键是Ctrl+Space,与搜狗输入法切换中英文的快捷键冲突了..可以改搜狗输入法的快捷键(Sh ...
- JS-闭包(Closures)和let声明块级作用域变量
闭包: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures 闭包是函数和声明该函数的词法环境的组合. let: https ...
- Linux 初始化系统 systemd - journald 日志
journalctl 中文手册 archlinux - journal systemd-journald 用于检索 systemd 的日志,是 systemd 自带的日志系统. 1. systemd- ...
- DEDE网站地图优化技巧
DEDE网站地图优化技巧-把网站地图生成在系统根目录,利于搜索引擎收录相信恨多用DEDECMS做站的朋友,为避免将data目录内的东西随便外泄,在robots中将data目录屏蔽了,但是DEDE默认的 ...
- tp 框架 -文件上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?ph ...
- 关于eclipse中的maven插件问题
最近上课讲eclipse 中的maven插件 有一个坑确实比较坑,实际上就是一个配置的原因. 就是在eclipse中设置java 的buildpath的时候,一般不注意往往都设置成了jre的,这样的话 ...
- C#清空StringBuilder的三种方法
1.Remove例: StringBuilder val = new StringBuilder(); val.Append("...."); val.Remove(0,val.L ...