MongoDB index management (1) - [9]

Please reprint from the source: http://eksliang.iteye.com/blog/2178427

I. Overview

      The index of the database is similar to the index of the book, with the index there is no need to flip the whole book. The index of the database is the same as this principle. First, search in the index. After finding the entry in the index, you can directly jump to the location of the target document, thereby increasing the query speed by several orders of magnitude.

      A query that doesn't use an index is called a full table scan (the term comes from relational databases), which means that the server has to look up an entire book to find the query results. The process is very similar to how we find information in a book without an index (table of contents): start on the first page and continue reading the entire book. In general, full table scans should be avoided as much as possible because they are very inefficient for large collections.

      The index of Mongodb is almost exactly the same as the index of relational database, so it is suitable for index optimization skills of relational database, so I won't talk about it here.

 

2. Create an index

Create an index using the db.collectionName.ensureIndex(...) method;

Reference example 1: Create a common index

 

> db.users.ensureIndex({"name":1})

      In this way, an index of name_1 is created on the name field above the users collection. {"name":1} indicates that the created index is in ascending order. If {"name":-1} indicates that the created index is in descending order.

 

Reference example 2: Create a common composite index

 

db.users.ensureIndex({"name":1,"age":1})

      This creates an index of name_1_age_1 on the name and age fields on the users collection.

 

Reference Example 3: Create a Unique Index

       A unique index ensures that each document in the collection has a unique value for the specified key. For example, if you want to ensure that different documents have different values ​​for the name key, you can create a unique index:

 

> db.dept.ensureIndex({"name":1},{"unique":true})

      After creating the unique index, if you want to add the following documents to the dept collection:

 

 

> db.dept.insert({ "_id" : 1, "name" : "ickes" })
> db.dept.insert({ "_id" : 2, "name" : "ickes" })

      You will find that only the first document is added, and an exception will be thrown when adding the second, so use a unique index to deal with the occasional key duplication problem, rather than filter duplicate keys at runtime. "_id" is the index of this type, which is automatically created when the collection is created.

 

Reference Example 3: Create a Composite Unique Index

    When creating a composite unique index, the values ​​of individual keys can be the same, but the combined value of all keys must be unique.

 

> db.users.ensureIndex({"name":1,"age":1},{"unique":true})

 

Reference Example 4: Removing Duplicates When Creating Unique Indexes  

      When creating a unique index on an existing collection, it may fail because there may already be duplicate values ​​in the collection, as follows:

 

> db.dept.find()
{ "_id" : 1, "name" : "ickes" }
{ "_id" : 2, "name" : "ickes" }
{ "_id" : 3, "name" : "ickes1" }
{ "_id" : 4, "name" : "eks" }
{ "_id" : 5, "name" : "eks" }
--从上面的集合中看出name已经有大量重复值,创建唯一索引时抛出异常
> db.dept.ensureIndex({"name":1},{"unique":true})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "ok" : 0,
        "errmsg" : "E11000 duplicate key error index: test.dept.$name_1  dup key
: { : \"eks\" }",
        "code" : 11000
}

     通常需要对已有的数据进行处理(可以使用聚合框架,后面会说),找出重复的数据,想办法处理。

     在极少数情况下,可能希望直接删除重复的值。创建索引时使用"dropDups"选项,如果遇到重复的值,第一个会被保留,之后的重复文档都会被删除。

 >  db.dept.ensureIndex({"name":1},{"unique":true,"dropDups":true})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

      "dropDups"会强制性的建立唯一索引,但是这个方式太粗暴了:你无法控制那些文档需要被保留,那些文档需要被删除(从上面打印的信息可以看出,如果文档被删除了,MongoDB也不会给出提示信息)。对于比较重要的数据,千万不要使用"dropDups".

参考实例四:创建稀疏索引

      唯一索引会把null值看做值,所以无法将缺少键的多个文档插入到建立的唯一索引的集合中。然而,在某些情况下,你可能希望唯一索引只针对包含相应键的文档生效。如果有一个可能存在也有可能不存在的字段,当字段存在时是唯一索引,不存时不做处理,这时就可以将unique和sparse选项组合在一起使用。

    使用sparse选项就可以创建稀疏索引。例如集合的结构如下:

> db.sparse.find()
{ "_id" : 1, "x" : 1 }
{ "_id" : 2, "x" : 2 }
{ "_id" : 3, "x" : null }
{ "_id" : 4 }

   创建稀疏索引

> db.sparse.ensureIndex({"x":1},{"unique":true,"sparse":true})

    稀疏索引不必是唯一的。只要去掉unique选项,就可以创建一个非唯一的稀疏索引

    MongoDB的稀疏索引与关系型数据库中的稀疏索引是完全不同的概念。基本上来说,MongoDB中的稀疏索引只是不需要将每个文档都作为索引条目。那么问题来了,根据是否使用稀疏索引,同一个查询的返回结果可能不同。

    例如上面文档,当在x上面执行查询时,他会返回相应匹配的文档:

> db.sparse.find({"x":{"$ne":1}}).hint({}) --hint({})强制不使用索引
{ "_id" : 2, "x" : 2 }
{ "_id" : 3, "x" : null }
{ "_id" : 4 }

    如果在x字段上面使用索引,那么{ "_id" : 4 }的文档将不会返回,因为他不在索引中,例如:

> db.sparse.find({"x":{"$ne":1}}).hint({"x":1})
{ "_id" : 3, "x" : null }
{ "_id" : 2, "x" : 2 }

 

 二、查看索引

 所有数据库索引信息都存储在system.indexes集合中。这是一个保留集合,不能在其中插入或者删除文档。只能通过ensureIndex({...})或者dropIndexes对他进行操作:

参考实例一:查看所有数据库建立的索引详情

> db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.users" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.dept" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.food" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.test" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.emp" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.blog" }
 ................省略!

 参考实例二:查看特定集合的索引信息

> db.users.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.users"
        },
        {
                "v" : 1,
                "key" : {
                        "name" : 1,
                        "age" : 1
                },
                "name" : "name_1_age_1",
                "ns" : "test.users"
        }
]
>

       这里最重要的字段是key和name,key说明了你创建索引时字段跟排序,name就是索引的名称,默认为key_dir_key_dir....的格式,"v"字段只在内部使用,用于标识索引的版本。如果你的索引不包含“v”:1这样的字段,说明你的索引是一种效率比较低的旧方式存储的。将MongoDB升级到至少2.0的版本,删除并重建这些索引,就可以把所有的存储方式升级到新的格式了。

 

三、标识索引

       集合中的每一个索引都有一个名称,用于唯一标识索引,也可以用于服务器端来删除索引。索引默认的命名方式是key1_dir1_key2_dir2....keyn_dirn,其中key就是索引的键,dir是索引的排序方向(1或者-1),如果索引中包含的键比较多,这种默认的命名方式就显得比较笨重,可以再创建索引时指定索引的名称。

参考实例:

> db.users.ensureIndex({"name":1,"age":1},{"name":"name_age1"})

 温馨提示:MongoDB索引名称的长度有限,所以新建复杂索引时可能需要自定义索引名称.

 

四、删除索引

参考实例一:删除集合里面的所有索引

 > db.users.dropIndexes()

 参考实例二:根据索引的key或者name删除集合里面的指定索引

> db.users.dropIndex("name_1_age_1")--根据索引的name删除
> db.users.dropIndex({"name":1,"age":1})--根据索引的key删除

 

     

       

 

 

 

    

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326380355&siteId=291194637