MongoDb进阶实践之七 MongoDB的索引入门
一、引言
好久没有写东西了,MongoDB系列的文章也丢下好长时间了。今天终于有时间了,就写了一篇有关索引的文章。一说到“索引”,用过关系型数据库的人都应该知道它是一个什么东西。当我们要访问的数据量大了的时候,可以通过建立索引来提高查询速度。关系型数据库有“索引”的概念,我们的MongoDB数据库也有索引的概念,今天我就来抛砖引玉,简单的说一说MongoDB文档数据库中的“索引”的概念。
二、简介
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构 。
三、详细操作
1、索引创建
1.1、语法:可以向指定集合中增加一个索引
ensureIndex()方法基本语法格式如下所示:
>db.collectionName.ensureIndex({KEY:1,KEY2:1,...KEYN:1})
说明:语法中 Key-Keyn 值为你要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
ensureIndex() 接收可选参数,可选参数列表如下:
Parameter Type Description
background Boolean 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false。
unique Boolean 建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
name string 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
dropDups Boolean 在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false.
sparse Boolean 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档。默认值为 false.
expireAfterSeconds integer 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
v index
version 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
weights document 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
default_language string 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
language_override string 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.
1.2、代码实例
//原始数据
>db.school.find({},{_id:});
{"name":"liulei","age":"","sex":"","address":"hebei"}
{"name":"zhangfei","age":"","sex":"","address":"shanxi"}
{"name":"guanyu","age":"","sex":"","address":"shanxi"}
{"name":"diaochan","age":"","sex":"","address":"guangdong"} //向name字段增加升序索引
>db.school.ensureIndex({"title":})
{
"createdCollectionAutomaticallly":false,
"numIndexesBefore":,
"numIndexesAfter":,
"ok":
} //ensureIndex() 方法中你也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)。
>db.school.ensureIndex({"title":,"age":-})
{
"createdCollectionAutomaticallly":false,
"numIndexesBefore":,
"numIndexesAfter":,
"ok":
}
2、检索索引
2.1、语法:检索当前指定集合所有的索引
getIndexes()方法基本语法格式如下所示:
>db.collectionName.getIndexes()
说明:会列出该集合内所有的索引。
2.2、代码实例
//原始数据
>db.school.find({},{_id:});
{"name":"liulei","age":"","sex":"","address":"hebei"}
{"name":"zhangfei","age":"","sex":"","address":"shanxi"}
{"name":"guanyu","age":"","sex":"","address":"shanxi"}
{"name":"diaochan","age":"","sex":"","address":"guangdong"} //获取当前school集合里面所有的索引
>db.school.getIndexes();
[
{
"v":,
"key":{"_id":},
"name":"_id_"
"ns":"school.school" },
{
"v":,
"key":{"name":},
"name":"name_1"
"ns":"school.school"
},
{
"v":,
"key":{"name":,"age":-},
"name":"name_1_age_-1"
"ns":"school.school"
}
]
3、删除索引
3.1、语法:删除指定集合里面指定名称的索引
dropIndex(INDEX-NAME)方法基本语法格式如下所示:
>db.collectionName.dropIndex(INDEX-NAME)
说明:删除索引的时候必须指定索引的名称。
3.2、语法:删除指定集合里面所有索引
dropIndexes()方法基本语法格式如下所示:
>db.collectionName.dropIndexes()
说明:该方法可以删除指定集合中所有的索引。
3.3、代码实例
//原始数据
>db.school.getIndexes();
[
{
"v":,
"key":{"_id":},
"name":"_id_"
"ns":"school.school" },
{
"v":,
"key":{"name":},
"name":"name_1"
"ns":"school.school"
},
{
"v":,
"key":{"name":,"age":-},
"name":"name_1_age_-1"
"ns":"school.school"
}
] //删除名称为是:name_1 的索引
>db.school.dropIndex("name_1");
{"nIndexesWas":,"ok":} //当前索引数据
>db.school.getIndexes();
[
{
"v":,
"key":{"_id":},
"name":"_id_"
"ns":"school.school" },
{
"v":,
"key":{"name":,"age":-},
"name":"name_1_age_-1"
"ns":"school.school"
}
] //删除所有索引数据
>db.school.dropIndexes();
{"nIndexesWas":,"msg":"non-_id indexes dropped for collection","ok":} //当前的索引数据
>db.school.getIndexes();
[
{
"v":,
"key":{"_id":},
"name":"_id_"
"ns":"school.school"
}
]
4、重建索引
4.1、语法:重新建立指定集合中所有的索引
reIndex()方法基本语法格式如下所示:
>db.collectionName.reIndex();
说明:重新建立指定集合的所有索引。
4.2、代码实例
//原始数据
>db.school.find({},{_id:});
{"name":"liulei","age":"","sex":"","address":"hebei"}
{"name":"zhangfei","age":"","sex":"","address":"shanxi"}
{"name":"guanyu","age":"","sex":"","address":"shanxi"}
{"name":"diaochan","age":"","sex":"","address":"guangdong"} //重新创建当前school集合里面所有的索引
>db.school.reIndex();
{
"nIndexesWas":,
"nIndexes":
"indexes":[
{
"v":,
"key":{"_id":},
"name":"_id_"
"ns":"school.school" },
{
"v":,
"key":{"name":},
"name":"name_1"
"ns":"school.school"
},
{
"v":,
"key":{"name":,"age":-},
"name":"name_1_age_-1"
"ns":"school.school"
}],
"ok":
}
5、统计指定集合索引文件的大小
5.1、语法:统计指定集合中所有索引文件大大小
totalIndexSize()方法基本语法格式如下所示:
>db.collectionName.totalIndexSize();
说明:统计指定集合中所有索引文件大大小。
5.2、代码实例
//统计school集合中索引文件的大小
>db.school.totalIndexSize();
四、使用索引的时候注意事项
1、额外开销
每个索引占据一定的存储空间,在进行插入,更新和删除操作时也需要对索引进行操作。所以,如果你很少对集合进行读取操作,建议不使用索引。
2、内存(RAM)使用
由于索引是存储在内存(RAM)中,你应该确保该索引的大小不超过内存的限制。
如果索引的大小大于内存的限制,MongoDB会删除一些索引,这将导致性能下降。
3、查询限制
索引不能被以下的查询使用:
正则表达式及非操作符,如 $nin, $not, 等。
算术运算符,如 $mod, 等。
$where 子句
所以,检测你的语句是否使用索引是一个好的习惯,可以用explain来查看。
4、索引键限制
从2.6版本开始,如果现有的索引字段的值超过索引键的限制,MongoDB中不会创建索引。
5、插入文档超过索引键限制
如果文档的索引字段值超过了索引键的限制,MongoDB不会将任何文档转换成索引的集合。与mongorestore和mongoimport工具类似。
6、最大范围
集合中索引不能超过64个,一般一个集合6-9索引就可以了
索引名的长度不能超过128个字符
一个复合索引最多可以有31个字段
五、结束
好了,就是这些了,我这个短短的文章只是起到了一个因子的作用,当然也希望对大家有帮助。我写的这些文章,也记录了我重拾记录的历史,争取在有时间的情况下,把自己的学习历程记录下来,为以后的自己铺平垫路。今天只是简单的讲了Mongodb的索引,如果以后有了新的学习心得,我在补充进来,不忘初心,继续努力吧。
MongoDb进阶实践之七 MongoDB的索引入门的更多相关文章
- MongoDb进阶实践之六 MongoDB查询命令详述(补充)
一.引言 上一篇文章我们已经介绍了MongoDB数据库的查询操作,但是并没有介绍全,随着自己的学习的深入,对查询又有了新的东西,决定补充进来.如果大家想看上一篇有关MongoDB查询的 ...
- MongoDb进阶实践之三 Mongodb基本命令详解
一.引言 从今天开始,我要正式开始介绍MongoDB的使用方法了.在此之前,我用了两篇文章分别介绍了如何在Linux系统和Windows系统上安装和配置MongoDB系统.如 ...
- MongoDb进阶实践之八 MongoDB的聚合初探
一.引言 好久没有写东西了,MongoDB系列的文章也丢下好长时间了.今天终于有时间了,就写了一篇有关聚合的文章.一说到“聚合”,用过关系型数据库的人都应该知道它是一个什么东西.关系型数据库有“聚合” ...
- MongoDb进阶实践之三 MongoDB查询命令详述
一.引言 上一篇文章我们已经介绍了MongoDB数据库的最基本操作,包括数据库的创建.使用和删除数据库,文档的操作也涉及到了文档的创建.删除.更新和查询,当然也包括集合的创建.重命 ...
- MongoDb进阶实践之五 MongoDB修改命令详述
一.引言 上一篇文章我们已经详细介绍了MongoDB数据库的有关查询的内容,但是这只是所有查询命令的冰山一角.所有查询命令都写完也没有必要,我只是写了一些常用的命令,对MongoDB的 ...
- MongoDb进阶实践之四 MongoDB查询命令详述
一.引言 上一篇文章我们已经介绍了MongoDB数据库的最基本操作,包括数据库的创建.使用和删除数据库,文档的操作也涉及到了文档的创建.删除.更新和查询,当然也包括集合的创建.重命名和删除.有了这些基 ...
- Redis进阶实践之七Redis和Lua初步整合使用(转载 7)
Redis进阶实践之七Redis和Lua初步整合使用 一.引言 Redis学了一段时间了,基本的东西都没问题了.从今天开始讲写一些redis和lua脚本的相关的东西,lua这个脚本是一个好东西,可以运 ...
- MongoDb进阶实践之一 如何在Linux(CentOS 7)上安装MongoDB
一.NoSQL数据简介 1.NoSQL概念 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",是 ...
- MongoDb进阶实践之一 如何在Linux系统上安装和配置MongoDB
转载来源:https://www.cnblogs.com/PatrickLiu/p/8630151.html 一.NoSQL数据简介 1.NoSQL概念 NoSQL(NoSQL = Not Only ...
随机推荐
- ORACLE 多表关联 UPDATE 语句
为了方便起见,建立了以下简单模型,和构造了部分测试数据: 在某个业务受理子系统BSS中, SQL 代码 --客户资料表 create table customers ( customer_id num ...
- 打包volley
1.如果电脑没有安装git和ant的话,需要安装git和ant,直接Google就可以,并配置环境变量 2.在命令行执行 git clone https://android.googlesource. ...
- 【面试笔试算法】Problem 7: 补提交卡(hiho题库)
时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho给自己定了一个宏伟的目标:连续100天每天坚持在hihoCoder上提交一个程序.100天过去了,小Ho查看自己的提交 ...
- PS图层混合算法之四(亮光, 点光, 线性光, 实色混合)
亮光模式: 根据绘图色通过增加或降低"对比度",加深或减淡颜色.如果绘图色比50%的灰亮,图像通过降低对比度被照亮,如果绘图色比50%的灰暗,图像通过增加对比度变暗. 线性光模式: ...
- OpenCV——色调映射
// define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...
- 不错的网络协议栈测试工具 — Packetdrill
Packetdrill - A network stack testing tool developed by Google. 项目:https://code.google.com/p/packetd ...
- Android实训案例(三)——实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果!
Android实训案例(三)--实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果! 感叹离春节将至,也同时感叹时间不等人,一年又一年,可是我依然是android道路上的小菜鸟,这篇讲 ...
- Java IO学习--(四)网络
Java中网络的内容或多或少的超出了Java IO的范畴.关于Java网络更多的是在我的Java网络教程中探讨.但是既然网络是一个常见的数据来源以及数据流目的地,并且因为你使用Java IO的API通 ...
- ORACLE复杂查询之连接查询
一.传统的连接查询 1.交叉连接:返回笛卡尔积 WHERE中限定查询条件,可以预先过滤掉掉不符合条件的记录,返回的只是两个表中剩余记录(符合条件的记录)的笛卡尔积. 2.内连接:参与连接的表地位平等, ...
- Web 前台优化
大型网站--前端性能优化和规范 2013-10-28 09:00 by 贤达, 2769 阅读, 10 评论, 收藏, 编辑 Web性能涉及的范围太广,但一般web开发者在程序上线以后很多都曾遇到 ...