mongo 索引查询计划

环境

MongoDB:3.4 
robomongo:1.0.RC1

explain 返回的数据

执行的语句:

db.urlcontents.find({ir_urltitle:{$regex:"科技"}, ir_groupname:"产业热点" }).sort({ir_urltime:-1}).explain("queryPlanner")
  • 1
  • 1

结果为:

{
    "cursor" : "BtreeCursor ir_groupname_1_ir_urltime_-1_ir_urltitle_1 multi"-索引名,
    "isMultiKey" : false --- 是否使用多键索引,
    "n" : 39 --- 返回的文档数量,
    "nscannedObjects" : 39 --- Mongodb按照索引指针去磁盘上查找实际文档次数,
    "nscanned" : 3103 --- 查找过的索引条目数,
    "nscannedObjectsAllPlans" : 3144,
    "nscannedAllPlans" : 12424,
    "scanAndOrder" : false --- 是否在内存中排序,
    "indexOnly" : false --- 是否使用了索引覆盖,
    "nYields" : 0 --- 为了让写入请求能够顺利执行,本次查询暂停的次数,
    "nChunkSkips" : 0,
    "millis" : 36 --- 查询计划花费的总时间,
    "indexBounds" : {
        "ir_groupname" : [ 
            [ 
                "产业热点", 
                "产业热点"
            ]
        ],
        "ir_urltime" : [ 
            [ 
                {
                    "$maxElement" : 1
                }, 
                {
                    "$minElement" : 1
                }
            ]
        ],
        "ir_urltitle" : [ 
            [ 
                "", 
                {}
            ], 
            [ 
                /科技/, 
                /科技/
            ]
        ]
    },
    "server" : "10-10-114-219:27018"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

覆盖索引 (indexOnly:true)

覆盖索引就是:当一个索引包含用户请求的所有字段,可以认为这个索引覆盖了本次查询。

所以在实际中,我们应该优先使用覆盖索引,而不是去获取实际的文档。这样可以保证工作集比较小,尤其与右平衡索引一起使用时。 ——《mongodb权威指南》

由于mongodb默认返回的字段中包含_id字段,所以最好使用投射来指定不要返回_id。 
如果一个查询使用的是覆盖索引,那么执行explain()时,indexOnly字段的值为true

唯一索引

唯一索引可以确保集合的每一个文档的指定键都有唯一值。例如,如果想保证不同文档的username键拥有不同的值,创建一个唯一索引就好了:

>db.users.ensureIndex({"username":1},{"unique":true})
  • 1
  • 1

如果试图向上面的集合中插入如下文档:

>db.users.insert({username:"bob"})
>db.users.insert({username:"bob"})
  • 1
  • 2
  • 1
  • 2

会报错:E11000 duplicate key error index : test.users.$username_1 dup key :{:”bob”} 
系统自动创建的_id就是唯一索引,这个唯一索引是不能被删除的,其他唯一索引可以删除。

复合唯一索引

在上面的基础上,创建多个键的所以即可。 
比如:

{username:1, age:1}
  • 1
  • 1

稀疏索引

>db.test.ensureIndex({email:1},{unique:true, sparse:true})
  • 1
  • 1

上面的意思是:创建了一个可选的唯一索引,也就是说,email这个字段可以没有,如果有,则必须是唯一的,不能重复。而上面唯一索引,即便字段为null或不存在,也不允许重复出现。sparse选项是用来创建稀疏索引的。

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

零碎知识

一个查询执行一个索引

mongodb查询一般情况下,是一次查询只能使用一个索引,但是$or是个例外:

假设我们创建了所以{x:1}和索引{y:1}

db.foo.find({"$or":[{'x':123},{"y":456}]})
  • 1
  • 1

这里执行两个索引,因为Mongodb是执行两次后查询后,把结果合并到一起的。


mongodb索引管理

mongodb索引统一在system.indexes集合中管理。 
这个集合只能通过ensureIndexdropIndexes来操作。


指定索引名

如果索引包含两个以上的键时,指定索引名称会更好看些。

>db.foo.ensureIndex({a:1,b:1,c:1,d:1},{"name":"自己取个名字"})
  • 1
  • 1

可以调用getLastError方法来查看索引是否创建成功。

查询索引信息

db.people.getIndexes()
  • 1
  • 1

删除索引

db.people.dropIndex("x_1_y_1")
{"nIndexesWas":3, "ok":1}
  • 1
  • 2
  • 1
  • 2

索引信息里的name字段就是该索引的唯一标识

创建索引,后台执行

db.people.ensureIndex({x:1,y:1},{background:1})

猜你喜欢

转载自blog.csdn.net/qq_35809876/article/details/76223454