第四部分 性能篇 第十章 MongoDB 索引

1、简介

MongoDB提供了多样性的索引支持,索引信息被保存在system.indexes中,且默认总是为_id创建索引,它的索引使用基本和MySQL的关系型数据库一样,其实可以这样说说,索引是凌驾于数据存储系统之上的另外一层系统,所以各种结构迥异的存储都有相同或者相似的索引实现及使用接口并不足为奇。

2、基础索引

在字段age上创建索引,1(升序),-1(降序)

<span style="font-family:SimHei;font-size:14px;">db.user.ensureIndex({age:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}
> db.user.getIndexes();
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.user"
        },
        {
                "v" : 1,
                "key" : {
                        "age" : 1
                },
                "name" : "age_1",
                "ns" : "test.user"
        }
]
>
</span>

说明

上列中显示出来了一共有2个索引,其中_id是创建表的时候自动创建的索引,此索引是不能够被删除的。

当系统已有大量数据时,创建索引的过程是个非常耗时的过程,我们可以在后台执行,只需要制定background:true即可。

>db.user.ensureIndex({age:1},{background:true})

3、文档索引

索引可以任何类型的字段,甚至文档。

<span style="font-family:SimHei;font-size:14px;">> db.factories.insert({name:"www",addr:{city:"BJ",state:"BEIJING"}});
WriteResult({ "nInserted" : 1 })</span>

在addr列上创建索引

<span style="font-family:SimHei;font-size:14px;">> db.factories.ensureIndex({addr:1});
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}</span>

下面的查询将会用到我们刚刚创建的索引

<span style="font-family:SimHei;font-size:14px;">> db.factories.find({addr:{city:"BJ",state:"BEIJING"}});
{ "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } }</span>

但是下面这个查询不会用到索引,因为查询的顺序跟索引建立的顺序不一样

<span style="font-family:SimHei;font-size:14px;">> db.factories.find({addr:{state:"BEIJING",city:"BJ"}});</span>

4、组合索引

跟其他数据库产品一样,MongoDB也是有组合索引的,下面我门将在addr.ctiy和addr.state上建立组合索引,当创建组合索引时,字段后面的1表示升序,-1表示降序,是用1还是用-1主要跟排序的时候或者指定范围内查询的时候有关的。

<span style="font-family:SimHei;font-size:14px;">> db.factories.ensureIndex({"addr.city":1,"addr.state":1});
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 2,
        "numIndexesAfter" : 3,
        "ok" : 1
}
> </span>

此时下面查询都用到了这个索引

<span style="font-family:SimHei;font-size:14px;">> db.factories.find({"addr.city":"BJ","addr.state":"BEIJING"});
{ "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } }
> </span>
<span style="font-family:SimHei;font-size:14px;">> db.factories.find({"addr.city":"BJ"});
{ "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } }
> </span>
<span style="font-family:SimHei;font-size:14px;">> db.factories.find().sort({"addr.city":1,"addr.state":1});
{ "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } }
>
</span>
<span style="font-family:SimHei;font-size:14px;">> db.factories.find().sort({"addr.city":1})
{ "_id" : ObjectId("54a935b579ceadf5fa8e2ec1"), "name" : "www", "addr" : { "city" : "BJ", "state" : "BEIJING" } }
>
</span>

5、唯一索引

只需要在ensureIndex命令中指定unique:true即可创建唯一索引,比如往表t4中插入两条记录:

<span style="font-family:SimHei;font-size:14px;">> db.t4.insert({firstname:"wang",lastname:"wu"});
WriteResult({ "nInserted" : 1 })
> db.t4.insert({firstname:"wang",lastname:"liu"});
WriteResult({ "nInserted" : 1 })
>
</span>

在t4表中建立唯一索引

<span style="font-family:SimHei;font-size:14px;">> db.t4.ensureIndex({firstname:1,lastname:1},{unique:true});
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}</span>

查看索引:

<span style="font-family:SimHei;font-size:14px;">> db.t4.getIndexes();
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.t4"
        },
        {
                "v" : 1,
                "unique" : true,
                "key" : {
                        "firstname" : 1,
                        "lastname" : 1
                },
                "name" : "firstname_1_lastname_1",
                "ns" : "test.t4"
        }
]</span>

6、强制使用索引

hint命令可以强制使用某个索引

<span style="font-family:SimHei;font-size:14px;">> db.t5.insert({name:"wangwu",age:20});
WriteResult({ "nInserted" : 1 })
> </span>

创建索引

<span style="font-family:SimHei;font-size:14px;">> db.t5.ensureIndex({name:1,age:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}</span>

查询(没有使用索引)

<span style="font-family:SimHei;font-size:14px;">> db.t5.find({age:{$lt:30}}).explain()
{
        "cursor" : "BasicCursor",
        "isMultiKey" : false,
        "n" : 1,
        "nscannedObjects" : 1,
        "nscanned" : 1,
        "nscannedObjectsAllPlans" : 1,
        "nscannedAllPlans" : 1,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 0,
        "server" : "localhost.localdomain:27017",
        "filterSet" : false
}</span>

强制使用索引

<span style="font-family:SimHei;font-size:14px;">> db.t5.find({age:{$lt:30}}).hint({name:1,age:1}).explain()
{
        "cursor" : "BtreeCursor name_1_age_1",
        "isMultiKey" : false,
        "n" : 1,
        "nscannedObjects" : 1,
        "nscanned" : 1,
        "nscannedObjectsAllPlans" : 1,
        "nscannedAllPlans" : 1,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 37,
        "indexBounds" : {
                "name" : [
                        [
                                {
                                        "$minElement" : 1
                                },
                                {
                                        "$maxElement" : 1
                                }
                        ]
                ],
                "age" : [
                        [
                                {
                                        "$minElement" : 1
                                },
                                {
                                        "$maxElement" : 1
                                }
                        ]
                ]
        },
        "server" : "localhost.localdomain:27017",
        "filterSet" : false
}</span>

7、删除索引

删除索引分为删除某张表的所有索引 和删除某张表的某个索引,具体如下:

<span style="font-family:SimHei;font-size:14px;">> db.t5.dropIndexes();
{
        "nIndexesWas" : 2,
        "msg" : "non-_id indexes dropped for collection",
        "ok" : 1
}
> </span>

删除t4表中的firstname索引

<span style="font-family:SimHei;font-size:14px;">> db.t4.dropIndex({firstname:1})
{
        "nIndexesWas" : 2,
        "ok" : 0,
        "errmsg" : "can't find index with key:{ firstname: 1.0 }"
}
>
</span>

-----------------------------------MongoDB系列文章更新-----------------------

第一部分 基础篇 第一章 走进MongoDB

第一部分 基础篇 第二章 安装MongoDB

第一部分 基础篇 第三章 MongoDB体系结构

第一部分 基础篇 第四章 MongoDB快速入门

第一部分 基础篇 第四章 MongoDB查询

第二部分 应用篇 第五章 MongoDB高级查询

第二部分 应用篇 第六章 MongoDB GridFS

第二部分 应用篇 第七章 MongoDB MapReduce

第三部分 管理篇 第八章 MongoDB服务管理

第三部分 管理篇 第九章 MongoDB shell之系统命令、用户命令

第三部分 管理篇 第九章 MongoDB shell之eval、进程

时间: 2024-10-13 01:09:15

第四部分 性能篇 第十章 MongoDB 索引的相关文章

第四部分 性能篇 第十一章 MongoDB 性能监控

声明:该文章主要来自<MongoDB实战>一书内容,主要想通过该书学习MongoDB的相应知识,加深理解,故写在自己的博文当中,作为记录在最后的章节中,会有一个自己集合MongoDB数据库应用的JavaEE的web应用. 1.MongoStat 此工具可以快速的查看某组运行中的MongoDB实例的统计信息,用法如下: [[email protected] bin]# ./mongostat connected to: 127.0.0.1 insert query update delete g

第五部分 架构篇 第二十章 MongoDB Sharding 架构( 片键选择)

1.选择片键 选择一个好的片键非常关键,如果选择了一个糟糕的片键,它可以立马或者在访问量变大时毁了你的应用程序,也有可能潜伏着,等待着,没准什么时候突然毁了你的应用程序. 另外一方面,如果你选择了一个好片键,只要应用程序还在正常运行,而且只要发现访问量提高就赶紧添加服务器,MongoDB就会确保一直正确地运行下去. 正如在前面所学的,片键决定了数据在集群中的分布情况,因此你会希望存在这样一个片键,它既能把读写分散开来,又能把正在使用的数据保持在一起,这些看似互相矛盾的目标在现实中却往往是可以实现

第四十二篇 Numpy的基本操作——索引相关

No.1. 使用np.argmin和np.argmax来获取向量元素中最小值和最大值的索引 No.2. 使用np.random.shuffle将向量中的元素顺序打乱,操作后,原向量发生改变:使用np.sort将乱序的向量进行排序,并将顺序的向量进行返回,原向量不发生改变 如果要将原来的乱序向量转化成顺序向量,需要使用x.sort,效果如下: No.3. 对矩阵中的元素进行排序 No.4. 使用np.argsort返回从小到大每个元素的索引值组成的向量 No.5. 使用np.partition返回

MongoDB索引(一) --- 入门篇:学习使用MongoDB数据库索引

这个系列文章会分为两篇来写: 第一篇:入门篇,学习使用MongoDB数据库索引 第二篇:进阶篇,研究数据库索引原理--B/B+树的基本原理 1. 准备工作 在学习使用MongoDB数据库索引之前,有一些准备工作要做,之后的探索都是基于这些准备工作. 首先需要建立一个数据库和一些集合,这里我就选用一个国内手机号归属地的库,大约32W条记录,数据量不大,不过做一些基本的分析是够了. 首先我们建立一个数据库,叫做db_phone,然后导入测试数据.测试数据就是一些手机号归属地的信息.单个文档长这个样子

Android 性能篇 -- 带你领略Android内存泄漏的前世今生

基础了解 什么是内存泄漏? 内存泄漏是当程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗.内存泄漏并不是指物理上的内存消失,这里的内存泄漏是指由程序分配的内存但是由于程序逻辑错误而导致程序失去了对该内存的控制,使得内存浪费. Java 内存分配策略 Java 程序运行时的内存分配策略有三种,分别是 静态分配 . 栈式分配 和 堆式分配 ,对应的三种存储策略使用的内存空间主要分别是 静态存储区(也称方法区) . 栈区 和 堆区 . ?? 静态存储区(方法区):主要存放 静态数据 . 全局

【朝花夕拾】Android性能篇之(六)Android进程管理机制

前言        Android系统与其他操作系统有个很不一样的地方,就是其他操作系统尽可能移除不再活动的进程,从而尽可能保证多的内存空间,而Android系统却是反其道而行之,尽可能保留进程.Android这样设计有什么优势呢?又是通过怎样的方法来管理这些被保留的进程的呢?Android用户又该如何正确使用手机从而更好发挥Android系统所特有的优势呢?本文将一一为您解开这些谜团.        一.Android进程管理的特殊设计 Linux系统对进程的管理方式是一旦进程活动停止,系统就

awk(四)高级篇

前面三篇总结了awk的基本结构,常用系统变量,流程控制,和函数. 这一篇总结下awk剩余的一些话题. getline函数 getline函数是从输入,标准输入,文件或管道读取另一行 getline和next有点类似,它俩都导致下一个输入行被读取.不同的,next语句将控制返回到脚本的顶部.而getline得到新的一行,但没有改变脚本的控制. next类似于sed中命令d. 而getline函数则类似于sed中命令N,不过和N还是有点小区别的. sed中的N命令,是读取新行,旧行和新行之间用换行符

Spring Boot干货系列:(四)Thymeleaf篇

Spring Boot干货系列:(四)Thymeleaf篇 原创 2017-04-05 嘟嘟MD 嘟爷java超神学堂 前言 Web开发是我们平时开发中至关重要的,这里就来介绍一下Spring Boot对Web开发的支持. 正文 Spring Boot提供了spring-boot-starter-web为Web开发予以支持,spring-boot-starter-web为我们提供了嵌入的Tomcat以及Spring MVC的依赖. 项目结构推荐 一个好的项目结构会让你开发少一些问题,特别是Spr

ubuntu下搭建android开发环境(四)核心篇安装AndroidStudio、sdk、jdk(by 星空武哥)

转载请标注原创地址:http://blog.csdn.net/lsyz0021/article/details/52215996 所有的软件均在ubuntu 14.04 LTS下测试 ubuntu下搭建android开发环境(一)安装ubuntu系统 ubuntu下搭建android开发环境(二)设置ubuntu的root管理员密码 ubuntu下搭建android开发环境(三)ubuntu安装搜狗输入法 ubuntu下搭建android开发环境(四)核心篇安装AndroidStudio.sdk