MongoDB索引的使用-单键索引

索引为频繁的查询提供高性能读取操作。

默认情况,新添加文档会在_id字段创建一个索引。

首先,向新集合testindx中插入1百万个文档。

for(i=0;i<1000000;i++){
  db.testindx.insert({"name":"user"+i,"age":Math.floor(Math.random()*120)})
}

执行结果:

然后,查询name值是user100的文档。并通过explain()分析执行过程。

db.testindx.find({"name":"user100"}).explain("allPlansExecution")

执行结果:

{ 
    "queryPlanner" : {
        "plannerVersion" : 1.0, 
        "namespace" : "xhb.testindx", 
        "indexFilterSet" : false, 
        "parsedQuery" : {
            "name" : {
                "$eq" : "user100"
            }
        }, 
        "winningPlan" : {
            "stage" : "COLLSCAN", 
            "filter" : {
                "name" : {
                    "$eq" : "user100"
                }
            }, 
            "direction" : "forward"
        }, 
        "rejectedPlans" : [

        ]
    }, 
    "executionStats" : {
        "executionSuccess" : true, 
        "nReturned" : 1.0, //1.返回一个文档结果
        "executionTimeMillis" : 650.0, //2.执行耗时650毫秒
        "totalKeysExamined" : 0.0, 
        "totalDocsExamined" : 1000000.0, //3.检查了1百万个文档
        "executionStages" : {
            "stage" : "COLLSCAN", //4.扫描了整个集合
            "filter" : {
                "name" : {
                    "$eq" : "user100"
                }
            }, 
            "nReturned" : 1.0, 
            "executionTimeMillisEstimate" : 548.0, 
            "works" : 1000002.0, 
            "advanced" : 1.0, 
            "needTime" : 1000000.0, 
            "needYield" : 0.0, 
            "saveState" : 7815.0, 
            "restoreState" : 7815.0, 
            "isEOF" : 1.0, 
            "invalidates" : 0.0, 
            "direction" : "forward", 
            "docsExamined" : 1000000.0
        }, 
        "allPlansExecution" : [

        ]
    }, 
    "serverInfo" : {
        "host" : "tommy", 
        "port" : 27017.0, 
        "version" : "4.0.3", 
        "gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c"
    }, 
    "ok" : 1.0
}

重点关注:

 

单键索引

创建索引的模版语句:ensureIndex({"字段":1,"字段":-1,......},{其他约束,可忽略})

db.testindx.ensureIndex({"name":1})

上面的语句在文档的name字段上创建了一个索引。再执行一下上面的查询语句。

db.testindx.find({"name":"user100"}).explain("allPlansExecution")

执行结果:

{ 
    "queryPlanner" : {
        "plannerVersion" : 1.0, 
        "namespace" : "xhb.testindx", 
        "indexFilterSet" : false, 
        "parsedQuery" : {
            "name" : {
                "$eq" : "user100"
            }
        }, 
        "winningPlan" : {
            "stage" : "FETCH", 
            "inputStage" : {
                "stage" : "IXSCAN", 
                "keyPattern" : {
                    "name" : 1.0
                }, 
                "indexName" : "name_1", 
                "isMultiKey" : false, 
                "multiKeyPaths" : {
                    "name" : [

                    ]
                }, 
                "isUnique" : false, 
                "isSparse" : false, 
                "isPartial" : false, 
                "indexVersion" : 2.0, 
                "direction" : "forward", 
                "indexBounds" : {
                    "name" : [
                        "[\"user100\", \"user100\"]"
                    ]
                }
            }
        }, 
        "rejectedPlans" : [

        ]
    }, 
    "executionStats" : {
        "executionSuccess" : true, 
        "nReturned" : 1.0, //1.返回一个结果文档
        "executionTimeMillis" : 1.0, //执行耗时1毫秒
        "totalKeysExamined" : 1.0, 
        "totalDocsExamined" : 1.0, //检查了一个文档
        "executionStages" : {
            "stage" : "FETCH", //执行方式:提取
            "nReturned" : 1.0, 
            "executionTimeMillisEstimate" : 0.0, 
            "works" : 2.0, 
            "advanced" : 1.0, 
            "needTime" : 0.0, 
            "needYield" : 0.0, 
            "saveState" : 0.0, 
            "restoreState" : 0.0, 
            "isEOF" : 1.0, 
            "invalidates" : 0.0, 
            "docsExamined" : 1.0, 
            "alreadyHasObj" : 0.0, 
            "inputStage" : {
                "stage" : "IXSCAN", 
                "nReturned" : 1.0, 
                "executionTimeMillisEstimate" : 0.0, 
                "works" : 2.0, 
                "advanced" : 1.0, 
                "needTime" : 0.0, 
                "needYield" : 0.0, 
                "saveState" : 0.0, 
                "restoreState" : 0.0, 
                "isEOF" : 1.0, 
                "invalidates" : 0.0, 
                "keyPattern" : {
                    "name" : 1.0
                }, 
                "indexName" : "name_1", 
                "isMultiKey" : false, 
                "multiKeyPaths" : {
                    "name" : [

                    ]
                }, 
                "isUnique" : false, 
                "isSparse" : false, 
                "isPartial" : false, 
                "indexVersion" : 2.0, 
                "direction" : "forward", 
                "indexBounds" : {
                    "name" : [
                        "[\"user100\", \"user100\"]"
                    ]
                }, 
                "keysExamined" : 1.0, 
                "seeks" : 1.0, 
                "dupsTested" : 0.0, 
                "dupsDropped" : 0.0, 
                "seenInvalidated" : 0.0
            }
        }, 
        "allPlansExecution" : [

        ]
    }, 
    "serverInfo" : {
        "host" : "tommy", 
        "port" : 27017.0, 
        "version" : "4.0.3", 
        "gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c"
    }, 
    "ok" : 1.0
}

重点关注:

由此可见,执行查询时扫描了整个集合,由于没有使用索引对性能造成了比较严重的影响。索引创建后,在查询执行时间方面产生了显著的差异。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值