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 ...
随机推荐
- BZOJ 2729: [HNOI2012]排队 排列组合 + 高精度
Description 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检.他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不 ...
- 2017华南理工华为杯D bx回文
比赛的时候队友过了,补补题XD. 题目链接:https://scut.online/p/125(赛后补题) 125. 笔芯回文 题目描述 bx有一个长度一个字符串S,bx可以对其进行若干次操作 ...
- kafka 知识点整理
一个partition只能被同一个消费组内一个消费者消费,所以在同一时间点上,订阅到同一个partition的consumer必然属于不同的Consumer Group. 因此,如果设置的partit ...
- python web自动化测试框架搭建(功能&接口)——接口测试模块
Python接口测试采用python读取excel的方法,通过requests库发送请求和接收响应.模块有: Data:用于存放excel用例的,用例格式: iutil: 接口公共方法,数据引擎.ht ...
- Vagrant 手册之网络 - 端口转发
原文地址 Vagrantfile 配置文件中端口转发的网络标识符:forwarded_port,例如: config.vm.network "forwarded_port", gu ...
- VS代码自动补全功能
VS代码自动补全功能 新建工程后,依次打开 工具>>代码段管理器>>选择C++>>点击 添加(A)...按钮 ,设置你的代码块的目录 复制以下代码并存为note.s ...
- MySQL 增删改语句
# DML语言 /* 数据操作语言: 插入:insert 修改:update 删除: delete */ 一.插入语句 insert /* 语法: 方式一: insert into 表名(列名,..) ...
- springboot连接mysql报错:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. ...
- java--反射原理及操作
1.反射原理 反射具体操作 15.反射的原理(********理解********) * 应用在一些通用性比较高的代码 中 * 后面学到的框架,大多数都是使用反射来实现的 * 在框架开发中,都是基于配 ...
- jQuery基础--总结
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...