美文网首页Node
MongoDB索引一(八)

MongoDB索引一(八)

作者: simuty | 来源:发表于2017-03-30 13:49 被阅读56次

    初识索引

    下篇--MongoDB索引二

    第一部分 插入测试数据

    #时间稍长
    for(var i = 0; i < 200000; i++){
        db.numbers.insert({"num": i});
    }
    

    验证结果

    > db.numbers.find().count()
    200000
    

    第二部分 索引前奏

    2.1 monogo关键字explain()

    explain()可以查看我们执行命令的内部实现,那么我们先看一下,再没有加索引之前,查询一条数据所需要的时间/扫描等字段

    没有对比就没有伤害

    没有伤害哪来的动力

    首先我们查阅官网中对explain()的介绍,在此它有个参数--verbose[冗长],往下看,发现verbose中又有三个可选参数

    1. queryPlanner: 默认model, 也就是执行的计划;
    2. executionStats: 打印执行的状态;
    3. allPlansExecution: 打印所有的执行的状态.
    

    返回的结果又有哪些呢?真是一个问题接着一个问题

    继续往下走,摘录一段英文

    Output
    
    cursor.explain() operations can return information regarding:
    
    1. queryPlanner, which details the plan selected by the query optimizer and lists the rejected plans;
    2. executionStats, which details the execution of the winning plan and the rejected plans; and
    3. serverInfo, which provides information on the MongoDB instance.
    

    也就是最多返回三个大的字段,

    1. queryPlanner: 查询优化器选择的计划细节,列出了拒绝计划;
    2. executionStats: 成功的执行计划细节和拒绝计划;
    3. serverInfo: 提供了MongoDB实例的信息。
    

    Mongo官网explain返回说明

    有了之上的explain()的主要的使用说明, 那么就可以继续往下继续了.

    第三部分 索引

    3.1 查询

    未加索引的查询

    #插叙最后3条数据
    > db.numbers.find({"num": {"$gt": 199996}}).explain("executionStats")
    
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.numbers",
            "indexFilterSet" : false,
            "parsedQuery" : {
                "num" : {
                    "$gt" : 199996
                }
            },
            "winningPlan" : {
        #全文扫描
                "stage" : "COLLSCAN",
                "filter" : {
                    "num" : {
                        "$gt" : 199996
                    }
                },
                "direction" : "forward"
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            
        #返回3个字段
            "nReturned" : 3,
        #花费时间[毫秒]
            "executionTimeMillis" : 92,
        #扫描到的索引
            "totalKeysExamined" : 0,
        #与之前返回字段[nscannedObjects]一致,
        #查询的个数
            "totalDocsExamined" : 200000,
            
            "executionStages" : {
        #全文扫描
                "stage" : "COLLSCAN",
                "filter" : {
                    "num" : {
                        "$gt" : 199996
                    }
                },
                "nReturned" : 3,
                ## 该查询根据index去检索获取具体数据的时间
                "executionTimeMillisEstimate" : 47,
                "works" : 200002,
                "advanced" : 3,
                "needTime" : 199998,
                "needYield" : 0,
                "saveState" : 1562,
                "restoreState" : 1562,
                "isEOF" : 1,
                "invalidates" : 0,
                "direction" : "forward",
                "docsExamined" : 200000
            }
        },
        
        "serverInfo" : {
            "host" : "huanghaowei.local",
            "port" : 27017,
            "version" : "3.4.0",
            "gitVersion" : "f4240c60f005be757399042dc12f6addbc3170c1"
        },
        "ok" : 1
    }
    
    
    3.2 添加索引
    > db.numbers.ensureIndex({"num": 1})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
    }
    
    > db.numbers.getIndexes()
    [
        {
            "v" : 2,
            "key" : {
                "_id" : 1
            },
            "name" : "_id_",
            "ns" : "test.numbers"
        },
        {
            "v" : 2,
            "key" : {
                "num" : 1
            },
            "name" : "num_1",
            "ns" : "test.numbers"
        }
    ]
    > 
    
    
    3.3 验证

    其中关于时间的字段少了不是一点的量,当然你也会发现其中,多了好多个字段,先不说其他的,这个时间量就完全可以俘获你的芳心吧 -.__.-

    > db.numbers.find({"num": {"$gt": 199996}}).explain("executionStats")
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.numbers",
            "indexFilterSet" : false,
            "parsedQuery" : {
                "num" : {
                    "$gt" : 199996
                }
            },
            "winningPlan" : {
                "stage" : "FETCH",
                "inputStage" : {
                #索引扫描
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "num" : 1
                    },
                    "indexName" : "num_1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "num" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "num" : [
                            "(199996.0, inf.0]"
                        ]
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 3,
        
    #可以对比一下这几个字段
            "executionTimeMillis" : 7,
        #仅此为我们需要的数据条数
        #nReturned=totalKeysExamined=totalDocsExamined(需要具体情况具体分析)
            "totalKeysExamined" : 3,
            "totalDocsExamined" : 3,
            
            "executionStages" : {
                "stage" : "FETCH",
                "nReturned" : 3,
                "executionTimeMillisEstimate" : 0,
                "works" : 4,
                "advanced" : 3,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "docsExamined" : 3,
                "alreadyHasObj" : 0,
                "inputStage" : {
            ##索引扫描
                    "stage" : "IXSCAN",
                    "nReturned" : 3,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 4,
                    "advanced" : 3,
                    "needTime" : 0,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "keyPattern" : {
                        "num" : 1
                    },
                    "indexName" : "num_1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "num" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "num" : [
                            "(199996.0, inf.0]"
                        ]
                    },
                    "keysExamined" : 3,
                    "seeks" : 1,
                    "dupsTested" : 0,
                    "dupsDropped" : 0,
                    "seenInvalidated" : 0
                }
            }
        },
        "serverInfo" : {
            ....        
        },
        "ok" : 1
    }
    > 
    
    
    3.4 删除索引

    不在需要的索引,我们可以将其删除。删除索引时,可以删除集合中的某一索引,可以删除全部索引。

    3.4.1 删除指定的索引dropIndex()
    db.COLLECTION_NAME.dropIndex("INDEX-NAME")
    
    

    删除指定的索引

    db.numbers.dropIndex("num")
    

    删除所有索引dropIndexes()

    > db.numbers.dropIndexes()
    

    相对数据集与复杂程度都属于入门,下篇继续.

    参考链接
    Monogo官网explain()
    Mongo官网explain返回说明
    MongoDB干货系列

    更多精彩内容请关注“IT实战联盟”哦~~~


    IT实战联盟.jpg

    相关文章

      网友评论

        本文标题:MongoDB索引一(八)

        本文链接:https://www.haomeiwen.com/subject/vfauottx.html