mongo 各种索引的用法

mongo 各种索引的用法

前提说一句:
查看数据库状态可以使用: db.stats();
查看某个集合状态使用: db.collection.stats()

  1. 索引的创建,删除
    db.records.createIndex( { score: 1 } )

这里score指定是1 , 意思是按照score进行asc排序, 如果是-1, 测试desc排序.
注意创建索引时要注意尽量使用db.tableName.ensureIndex({index}, {background: true}), MongoDB 提供了两种建索引的访问,一种是 background 方式,不需要长时间占用写锁,另一种是非 background 方式,需要长时间占用锁。使用 background 方式就可以解决问题。 例如,为超大表 posts 建立索引, 千万不用使用
如何杀死失控的索引创建过程: http://www.jianshu.com/p/f9d71763e844
2. 创建组合索引:

    db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } 

2.1. 创建唯一索引, 唯一索引的作用是确保集合中某一个字段的唯一性
db.collection.createIndex({username:1}, {unique:true})
如果为一个已经存在的表创建唯一索引,且对于重复数据保留那一条不关心,可以使用db.collection.createIndex({username:1}, {unique:true, dropDups:true})
3.获取当前集合的索引

    db.collection.getIndexes();

4.删除索引

    db.collection.dropIndex(索引名)
    删除所有索引: db.collection.dropIndexes()

5.分析索引

   db.collection.find().explain(分析模式)

分析模式有一下值: queryPlanner(默认), executionStats, allPlansExecution.
索引输出分析

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "wm.scoreHistory", // 查询的表
        "indexFilterSet" : false, // 针对该query是否有indexfilte
        "parsedQuery" : {
            "memberId" : {
                "$eq" : ObjectId("589ad1c89cd0b3003635e4d9")
            }
        },
        "winningPlan" : {   // 最优化的查询器
            "stage" : "FETCH",// 最优执行计划的stage,stage有数个模式,这里的意思是说当前查询 FETCH效率最快
            "inputStage" : { // 来描述字stage
                "stage" : "IXSCAN",  // stage模式
                "keyPattern" : {  // index的内容
                    "memberId" : 1,
                    "createdAt" : -1
                },
                "indexName" : "memberId_1_createdAt_-1", // index 的名字
                "isMultiKey" : false, //是不是组合索引
                "isUnique" : false,// 是不是唯一索引
                "isSparse" : false, // 是不是稀疏索引
                "isPartial" : false,
                "indexVersion" : 1,
                "direction" : "forward",// 查询顺序, 如果sort({xx:-1}), 这里将是backward
                "indexBounds" : { // 索引扫秒的范围,如果没有制定范围就是[MaxKey, MinKey],这主要是直接定位到mongodb的chunck中去查找数据,加快数据读取。
                    "memberId" : [
                        "[ObjectId('589ad1c89cd0b3003635e4d9'), ObjectId('589ad1c89cd0b3003635e4d9')]"
                    ],
                    "createdAt" : [
                        "[MaxKey, MinKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : [ ] //其他执行计划(非最优而被查询优化器reject的)的详细返回,其中具体信息与winningPlan的返回中意义相同,故不在此赘述
    },
    "executionStats" : {
        "executionSuccess" : true, // 执行是否成功
        "nReturned" : 46, // 满足条件的返回文档的条数
        "executionTimeMillis" : 98, // 整条语句执行时间
        "totalKeysExamined" : 46, // 索引整体扫描的文档个数
        "totalDocsExamined" : 46, // document扫描个数
        "executionStages" : {
            "stage" : "FETCH",// 使用的stage模式
            "nReturned" : 46, // 返回文档条数
            "executionTimeMillisEstimate" : 80,  // 根据当前索引去检索document返回46条数据的时间
            "works" : 47,
            "advanced" : 46,
            "needTime" : 0,
            "needYield" : 0,
            "saveState" : 1,
            "restoreState" : 1,
            "isEOF" : 1,
            "invalidates" : 0,
            "docsExamined" : 46,
            "alreadyHasObj" : 0,
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : 46,
                "executionTimeMillisEstimate" : 80,  // 该查询扫描46行index所用时间
                "works" : 47,
                "advanced" : 46,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 1,
                "restoreState" : 1,
                "isEOF" : 1,
                "invalidates" : 0,
                "keyPattern" : {
                    "memberId" : 1,
                    "createdAt" : -1
                },
                "indexName" : "memberId_1_createdAt_-1",
                "isMultiKey" : false,
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 1,
                "direction" : "forward",
                "indexBounds" : {
                    "memberId" : [
                        "[ObjectId('589ad1c89cd0b3003635e4d9'), ObjectId('589ad1c89cd0b3003635e4d9')]"
                    ],
                    "createdAt" : [
                        "[MaxKey, MinKey]"
                    ]
                },
                "keysExamined" : 46,
                "dupsTested" : 0,
                "dupsDropped" : 0,
                "seenInvalidated" : 0
            }
        }
    },
    "serverInfo" : {
        "host" : "f4acb39dab64",
        "port" : 27017,
        "version" : "3.2.7",
        "gitVersion" : "4249c1d2b5999ebbf1fdf3bc0e0e3b3ff5c0aaf2"
    },
    "ok" : 1
}

第一层,executionTimeMillis
最为直观explain返回值是executionTimeMillis值,指的是我们这条语句的执行时间,这个值当然是希望越少越好。 其中有3个executionTimeMillis,分别是: executionStats.executionTimeMillis,
executionStats.executionStages.executionTimeMillisEstimate,
executionStats.executionStages.inputStage.executionTimeMillisEstimate.
第二层,index与document扫描数与查询返回条目数
这个主要讨论3个返回项,nReturned、totalKeysExamined、totalDocsExamined,分别代表该条查询返回的条目、索引扫描条目、文档扫描条目。 这些都是直观地影响到executionTimeMillis,我们需要扫描的越少速度越快。
对于一个查询,我们最理想的状态是:

nReturned=totalKeysExamined=totalDocsExamined

第三层,stage状态分析
那么又是什么影响到了totalKeysExamined和totalDocsExamined?是stage的类型。类型列举如下:
COLLSCAN:全表扫描
IXSCAN:索引扫描
FETCH:根据索引去检索指定document
SHARD_MERGE:将各个分片返回数据进行merge
SORT:表明在内存中进行了排序
LIMIT:使用limit限制返回数
SKIP:使用skip进行跳过
IDHACK:针对_id进行查询
SHARDING_FILTER:通过mongos对分片数据进行查询
COUNT:利用db.coll.explain().count()之类进行count运算
COUNTSCAN:count不使用Index进行count时的stage返回
COUNT_SCAN:count使用了Index进行count时的stage返回
SUBPLA:未使用到索引的$or查询的stage返回
TEXT:使用全文索引进行查询时候的stage返回
PROJECTION:限定返回字段时候stage的返回
对于普通查询,我希望看到stage的组合(查询的时候尽可能用上索引):
Fetch+IDHACK
Fetch+ixscan
Limit+(Fetch+ixscan)
PROJECTION+ixscan
SHARDING_FITER+ixscan
COUNT_SCAN
不希望看到包含如下的stage:
COLLSCAN(全表扫描),SORT(使用sort但是无index),不合理的SKIP,SUBPLA(未用到index的\$or),COUNTSCAN(不使用index进行count)
6.指定索引

   db.collection.find().hint({"score":1}) 或者
   db.collection.find().hint("score_1") 索引名

7.唯一索引, 当为一个字段创建唯一索引后,在集合内,这个字段不能存储相同的值,

    db.collection.createIndex({"userid":1},{"unique":true})

当mongo要索引一个字段时,如果一篇文档中没有这个字段,这篇文档就会被索引为null,因为唯一索引不能有重复值,所以必须和稀疏索引配合使用,如:

db.collection.ensureIndex({a:1},{unique:true,sparse:true})
  1. 稀疏索引,当一个集合的某一个字段并不是必须的,有些记录没有,这是需要稀疏索引, 索引中将不包含没有labels字段的文档。
    db.collection.createIndex({labels:1},{sparse:true})
  1. 知道固定集合,集合大小创建时指定。如果没有空间了,就会自动删除最老的文档,以释放空间。(类似以一个循环队列)
db.createCollection("member",{"capped":true,"size":100,"max":10}); 

创建:Size:存储空间为: 100kb Max: 记录数,最大存放条数

猜你喜欢

转载自blog.csdn.net/qq_32239417/article/details/56282137