MongoDB 单键(列)索引

MongoDB支持基于集合文档上任意列创建索引。缺省情况下,所有的文档的_id列上都存在一个索引。基于业务的需要,可以基于一些重要的查询和操作来创建一些额外的索引。这些索引可以是单列,也可是多列(复合索引),多键索引,地理空间索引,文本索引以及哈希索引等。 本文主要描述在基于文档上的单列来创建索引。

一、创建语法

    语法:db.collection.createIndex(keys, options)

    keys:
            一个包含字段和值键值对的文档,指定该键即在该键上创建索引,如{age:1}
            创建索引时可以指定索引为升序或者降序,索引键之后的值为1为升序,-1为降序
            可以基于多个键创建索引,每一个键上可以指定升序或降序

    options
            该options为创建索引时的相关选项,该选项为文档类型,以下列出几个常用的选项:

            background  boolean  可选选项(缺省值false)
                    是否在后台创建索引(不阻塞数据库活动),其值为布尔型,即true或false

            unique boolean       可选选项(缺省值false)
                    用于指定创建的索引是否唯一,其值为布尔型,即true或false

            name    string         可选选项
                    是否指定索引的名字。在未指定的情况下,MongoDB会产生一个由键名+排序构成的索引名

            partialFilterExpression document  可选选项
                    部分过滤表达式,如果指定,索引只引用匹配过滤器表达式的文档。
                    常用的过滤器包括:
                            equality expressions (i.e. field: value or using the $eq operator),
                            $exists: true expression,
                            $gt, $gte, $lt, $lte expressions,
                            $type expressions,
                            $and operator at the top-level only

            sparse  boolean      可选选项(缺省值false)
                    指定该索引是否为间隙索引,间隙索引占用更少的磁盘空间
                    从3.2版本之后,MongoDB支持部分索引,部分索引是间隙索引的超集
                    如果使用MongoDB,建议优先使用部分索引

            expireAfterSeconds  integer 可选选项
                    指定一个值,以秒为单位,即TTL值,用于控制多久MongoDB保留此集合中的文档
                    该选项适用于TTL索引

            storageEngine   document 可选选项
                    允许用户在创建索引时指定每个索引所使用的存储引擎的配置。
                    该引擎选项的值形式为: { <storage-engine-name>: <options> }
                    存储引擎配置在创建索引是被验证以及记录到oplog,支持副本集成员使用不同的存储引擎

二、单键(列)索引示意图

如下图所示,基于文档score键(列)创建一个单键索引

三、演示创建单列索引

1、演示环境

> db.version()
3.2.10
> db.example.find({},{"_id":0})
{ "id" : 1, "ename" : "leshami", "blog" : "http://blog.csdn.net/leshami", "name" : "robinson_0612" }

演示集合数据,可以参考:http://blog.csdn.net/leshami/article/details/52672310

//查看任意的一个文档
> db.persons.find().limit(1).pretty()
{
        "_id" : ObjectId("5812cbaaa129eed14b46458d"),
        "name" : "robinson.cheng",
        "age" : 25,
        "email" : "robinson.cheng@qq.com",
        "score" : {
                "c" : 89,
                "m" : 96,
                "e" : 87
        },
        "country" : "USA",
        "books" : [
                "JS",
                "C++",
                "EXTJS",
                "MONGODB"
        ]
}

//查看当前集合上已经存在的索引
> db.persons.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1  //该集合上只有一个基于_id的缺省索引
                },
                "name" : "_id_",
                "ns" : "test.persons"
        }
]                               

2、创建单键(列)索引

//下面我们基于集合persons上文档age列来创建一个升序索引
> db.persons.createIndex({age:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,  //索引创建前的索引数目为1
        "numIndexesAfter" : 2,   //索引创建后的索引数目为2
        "ok" : 1
}
> 

//下面使用explain方法查看索引是否被使用
//有关获取执行计划的方法可查看:http://blog.csdn.net/leshami/article/details/53521990
> db.persons.find({age:25}).explain()
{
  "queryPlanner" : {
           ..............
          "winningPlan" : {
                  "stage" : "FETCH",
                  "inputStage" : {
                          "stage" : "IXSCAN", //此处提示使用索引扫描
                          "keyPattern" : {
                                  "age" : 1
                          },
                          "indexName" : "age_1",//索引名字为age列+排列顺序
                          "isMultiKey" : false, //是否为多键索引
                          "isUnique" : false,   //是否为唯一索引
                          "isSparse" : false,   //是否为间隙索引
                          "isPartial" : false,  //是否为部分索引
                          "indexVersion" : 1,   //索引的版本
                          "direction" : "forward",//索引查询的方向
                          "indexBounds" : {
                                  "age" : [
                                          "[25.0, 25.0]"
                 .........
  "ok" : 1
}

//下面通过$gt过滤,这个也将会使用到索引,此处省略执行计划
> db.persons.find({age:{$gt:25}}).explain()

3、基于内嵌文档列创建单列索引

//MongoDB支持在内嵌文档上列上创建单列索引,创建方法与文档上单列创建方法类似。
//在内嵌文档列上的创建,可以使用"." 方式来创建。即内嵌文档列.成员名的方法。
//在内嵌文档中使用索引进行等值匹配,其字段的顺序应该实现精确配置。 

//下面在内嵌文档score.c上创建索引
> db.persons.createIndex({"score.c":1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 2,
        "numIndexesAfter" : 3,
        "ok" : 1
}

//查看score.c值为89的查询的执行计划
> db.persons.find({"score.c":89}).explain()
{
 "queryPlanner" : {
   .......
         "winningPlan" : {
                 "stage" : "FETCH",
                 "inputStage" : {
                         "stage" : "IXSCAN",  //基于索引扫描
                         "keyPattern" : {
                                 "score.c" : 1
                         },
                         "indexName" : "score.c_1", //索引的名字
                         "isMultiKey" : false,
                         "isUnique" : false,
                         "isSparse" : false,
                         "isPartial" : false,
                         "indexVersion" : 1,
                         "direction" : "forward",
                         "indexBounds" : {
                                 "score.c" : [
                                         "[89.0, 89.0]"
       ............
 "ok" : 1
}

4、基于内嵌文档创建索引

//基于内嵌文档创建索引只需要指定内嵌文档键(列)即可
//基于内嵌文档创建索引包含嵌入文档的全部内容,而不是嵌入文档的部分列

> db.persons.createIndex({score:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 3,
        "numIndexesAfter" : 4,
        "ok" : 1
}

//查看基于内嵌文档查询的执行计划及其统计信息
> db.persons.find({score:{c:89,m:96,e:87}}).explain("executionStats")
{
    "queryPlanner" : {
    ........
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 1,            //返回一个文档
        "executionTimeMillis" : 0,
        "totalKeysExamined" : 1,   //总共检查的键为1个
        "totalDocsExamined" : 1,   //总共检查的文档为1个
        "executionStages" : {
            "stage" : "FETCH",
            "nReturned" : 1,
            "executionTimeMillisEstimate" : 0,
            "works" : 2,
            "advanced" : 1,
            "needTime" : 0,
            "needYield" : 0,
            "saveState" : 0,
            "restoreState" : 0,
            "isEOF" : 1,
            "invalidates" : 0,
            "docsExamined" : 1,
            "alreadyHasObj" : 0,
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : 1,
                "executionTimeMillisEstimate" : 0,
                "works" : 2,
                "advanced" : 1,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "keyPattern" : {
                    "score" : 1
                },
                "indexName" : "score_1",
                "isMultiKey" : false,
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 1,
                "direction" : "forward",
                "indexBounds" : {
                    "score" : [
                        "[{ c: 89.0, m: 96.0, e: 87.0 }, { c: 89.0, m: 96.0, e: 87.0 }]"
                    ]
                },
                "keysExamined" : 1,
                "dupsTested" : 0,
                "dupsDropped" : 0,
                "seenInvalidated" : 0
            }
        }
     ..........
    "ok" : 1
}

5、查看集合上已经存在的索引

//从下面的查询可知,当前persons集合上存在4个索引
> db.persons.getIndexes()
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "test.persons"
    },
    {
        "v" : 1,
        "key" : {
            "age" : 1
        },
        "name" : "age_1",
        "ns" : "test.persons"
    },
    {
        "v" : 1,
        "key" : {
            "score.c" : 1
        },
        "name" : "score.c_1",
        "ns" : "test.persons"
    },
    {
        "v" : 1,
        "key" : {
            "score" : 1
        },
        "name" : "score_1",
        "ns" : "test.persons"
    }
]

时间: 2024-09-21 20:26:21

MongoDB 单键(列)索引的相关文章

MongoDB 多键索引

在MongoDB中可以基于数组来创建索引.MongoDB为数组每一个元素创建索引值.多键索引支持数组字段的高效查询.多键索引能够基于字符串,数字数组以及嵌套文档进行创建.本文主要描述多键索引并给出演示示例. 一.多键索引 基于一个数组创建索引,MongoDB会自动创建为多键索引,无需刻意指定 多键索引也可以基于内嵌文档来创建 多键索引的边界值的计算依赖于特定的规则 注,多键索引不等于在文档上的多列创建索引(复合索引) 创建语法 db.coll.createIndex( { <field>: &

外键列上是否需要索引

其实这个问题应该算是老生常谈了.这两天看concept看到这里,于是就在说说这个问题.     外键列上缺少索引会带来两个问题,限制并发性.影响性能.而这两个问题中的任意一个都可能会造成严重性能问题. 无论是Oracle的官方文档,还是在Tom的书中都说明了两种情况下可以忽略外键上的索引.其实我认为不需要那么麻烦,与增加一个索引所带来的性能开销和磁盘空间开销相比,确实索引可能引发的问题要严重得多.因此,我会选择在所有的外键列上添加索引,虽然可能导致创建了部分多余的索引,但是这样相除了外键约束由于

主键和聚集索引和单列索引和多列索引

  1. 主键与聚集索引 首先澄清一个概念,主键并不等于聚集索引.(这不是废话么,如果是同一个东西,微软也不会叫两个不同的名字了) 一个表只能有一个聚集索引,数据在物理上是按照聚集索引的顺序来存放的. 主键分为聚集的主键和非聚集的主键.默认是聚集的主键.下面代码是SqlServer自动生成的CREATE TABLE 代码,注意设定主键那句话中的' CLUSTERED',即表示聚集的主键. /****** Object: Table [dbo].[User] Script Date: 03/28/

8天学通MongoDB——第四天 索引操作

原文:8天学通MongoDB--第四天 索引操作     这些天项目改版,时间比较紧,博客也就没跟得上,还望大家见谅.     好,今天分享下mongodb中关于索引的基本操作,我们日常做开发都避免不了要对程序进行性能优化,而程序的操作无非就是CURD,通常我们 又会花费50%的时间在R上面,因为Read操作对用户来说是非常敏感的,处理不好就会被人唾弃,呵呵.     从算法上来说有5种经典的查找,具体的可以参见我的算法速成系列,这其中就包括我们今天所说的"索引查找",如果大家对sql

键列信息不足或不正确,更新影响到多行 的解决方法

有一次直接通过MMC进行某表的复制粘贴操作,后台修改内容时提示:键列信息不足或不正确,更新影响到多行,经过多次尝试,终于找到解决方法! 一个解决 键列信息不足或不正确,更新影响到多行 的解决方法. 那就是在设计表功能里,先把ID索引的列删除掉.然后点击保存表. 接着再重新建立一个新的ID主键标识字段,这个时间,就可以任意修改或删除刚才出错的表内容了. 如果你想修正ID列,那也只要把该列的标识和主键属性先去掉,修改完成后重新赋予就行了. 千万不要写重复了就可以! 试试解决这个问题吧:键列信息不足或

SQL Server 索引和表体系结构(包含列索引)

原文:SQL Server 索引和表体系结构(包含列索引) 包含列索引 概述 包含列索引也是非聚集索引,索引结构跟聚集索引结构是一样,有一点不同的地方就是包含列索引的非键列只存储在叶子节点:包含列索引的列分为键列和非键列,所谓的非键列就是INCLUDE中包含的列,至少需要有一个键列,且键列和非键列不允许重复,非键列最多允许1023列(也就是表的最多列-1),由于索引键列(不包括非键)必须遵守现有索引大小的限制(最大键列数为 16,总索引键大小为 900 字节)的要求所以引进了包含列索引. 正文

使用自增长键列值的统计信息

原文:使用自增长键列值的统计信息 今天的文章里我想谈下SQL Server里非常普遍的问题:如何处理用自增长键列的统计信息.我们都知道,在SQL Server里每个统计信息对象都有关联的直方图.直方图用多个步长描述指定列数据分布情况.在一个直方图里,SQL Server最大支持200的步长,但当你查询的数据范围在直方图最后步长后,这是个问题.我们来看下面的代码,重现这个情形:  1 -- Create a simple orders table 2 CREATE TABLE Orders 3 (

Oracle外键不加索引引起死锁示例_oracle

--创建一个表,此表作为子表 create table fk_t as select *from user_objects; delete from fk_t where object_id is null; commit; --创建一个表,此表作为父表 create table pk_t as select *from user_objects; delete from pk_t where object_id is null; commit; --创建父表的主键 alter table PK

ORACLE中关于外键缺少索引的探讨和总结

    在ORACLE数据库中,定义外键约束时,ORACLE是不会自动创建对应索引的,必须手动在外键约束相关的列上创建索引.那么外键字段上是否有必要创建索引呢?如果有必要的话,巡检时,如何找出外键字段上没有创建索引的相关表,并生成对应的索引的脚本呢?   外键缺失索引影响   外键列上缺少索引会带来三个问题,限制并发性.影响性能.还有可能造成死锁.所以对于绝大部分场景,我们应该尽量考虑在外键上面创建索引   1. 影响性能. 如果子表外键没有创建索引,那么当父表查询关联子表时,子表将进行全表扫描