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 ...
随机推荐
- 【翻译】Ext JS最新技巧——2014-9-10
原文:Top Support Tips Greg Barry:删除网格单元格的焦点 在Ext JS 5.0.1,添加了一些与可访问性和支持ARIA有关的显著改进.虽然鼓励使用这些新增功能,但默认样式可 ...
- Android 获取某apk的签名信息,可用作防盗版进入。
转载请标明出处: http://write.blog.csdn.net/postedit/45721779作者:skay 一般项目中有防盗版的需求,必须是正版软件才能使用,这就需要获取当前安装包的签 ...
- 算法学习笔记(一)C++排序函数、映射技巧与字典树
1.头文件algorithm中有函数sort()用于排序,参数为:排序起始地址,排序结束地址,排序规则(返回bool型)例如,要将array[] = {5,7,1,2,9}升序排列,则使用: bool ...
- git remote
在git里,服务器上的仓库在本地称之为remote. 直接clone一个仓库: $: git clone git@search.ued.taobao.net:projects/search.git 另 ...
- 【Android 应用开发】Android - 时间 日期相关组件
源码下载地址 : -- CSDN : http://download.csdn.net/detail/han1202012/6856737 -- GitHub : https://github.co ...
- 仿百度壁纸客户端(一)——主框架搭建,自定义Tab+ViewPager+Fragment
仿百度壁纸客户端(一)--主框架搭建,自定义Tab+ViewPager+Fragment 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment ...
- C语言关键字static的绝妙用途
为什么要说static妙,它确实是妙,在软件开发或者单片机开发过程中,大家总以为static就是一个静态变量,在变量类型的前面加上就自动清0了,还有就是加上static关键字的,不管是变量还是关键字, ...
- 如何设计一个可用的web容器
之前在另外一个平台(http://www.jointforce.com/jfperiodical/article/1035)发表的一篇文章,现在发布到自己的博客上. 开发一个web容器涉及很多不同方面 ...
- iOS中判断照片和相机权限
1.照片权限判断 在iOS6之后,app中使用照片(即自带相册)需要用户权限验证,所以我们可以做一个权限判断给出友好的提示或者界面效果. 相册判断需要导入 <AssetsLibrary/Asse ...
- 高通Android display架构分析
目录(?)[-] Kernel Space Display架构介绍 函数和数据结构介绍 函数和数据结构介绍 函数和数据结构介绍 数据流分析 初始化过程分析 User Space display接口 K ...