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 ...
随机推荐
- python,os操作文件,文件路径(上一级目录)
python获取文件上一级目录:取文件所在目录的上一级目录 os.path.abspath(os.path.join(os.path.dirname('settings.py'),os.path.pa ...
- android开发之http协议
http协议学习系列 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web C ...
- UE4 Hello World 创建第一个UE4工程
首先先熟悉几个UE4常用的类 AGameMode(控制整个项目的逻辑) The GameMode defines the game being played. It governs thegame r ...
- IP协议详解(转)
本文转载自博文协议森林05 我尽力 (IP协议详解).这篇博文写的很有趣味,特转载! IPv4与IPv6头部的对比 我们已经在IP接力中介绍过,一个IP包分为头部(header)和数据(payload ...
- 股票K线图
代码链接地址:点击打开链接
- IDE
IDE(Integrated Development Environment,集成开发环境).DE集成开发环境(简称IDE)软件是用于程序开发环境的应用程序,一般包括代码编辑器.编译器.调试器和图形用 ...
- OpenCV——去雾
这是一个简化的实现算法,完整的算法请参考: Single Image Haze Removal Using Dark Channel Prior --CVPR 2009 // define head ...
- 设计模式学习--组合模式,c++代码
下面是组合模式的UML类图: <span style="font-family:Microsoft YaHei;font-size:18px;"><span st ...
- 在linux下搭建STM32工程
转载自康神博客:http://blog.csdn.net/u013298300/article/details/50243935 在LINUX下开始一个STM32工程 在LINUX下开始一个STM32 ...
- Redis的集群配置
如果我们redis的压力很大,如果我们的并发高到我们读数据和写数据都有了很大压力. 那么我们可能就需要把redis分开部署,并且配置为一个『主从』的状态. 在服务器上构筑Redis的集群配置: 1.切 ...