当前位置:Gxlcms > 数据库问题 > MongoDB 索引相关知识

MongoDB 索引相关知识

时间:2021-07-01 10:21:17 帮助过:2人阅读

      MongoDB和MySQL一样,都会产生慢查询,所以都需要对其进行优化:包括创建索引、重构查询等。现在就说明在MongoDB下的索引相关知识点,可以通过这篇文章MongoDB 查询优化分析了解MongoDB慢查询的一些特点。

执行计划分析:

      因为MongoDB也是BTree索引,所以使用上和MySQL大致一样。通过explain查看一个query的执行计划,来判断如何加索引,explain在3.0版本的时候做了一些改进,现在针对这2个版本进行分析:

3.0之前:

zjy:PRIMARY> db.newtask.find({"b":"CYHS1301942"}).explain()
{
    "cursor" : "BtreeCursor b_1_date_1", #游标类型:BasicCursor(全表扫描)、BtreeCursor(BTree索引扫描)、GeoSearchCursor(地理空间索引扫描)。
    "isMultiKey" : false,
    "n" : 324,  #返回的结果数,count()。
    "nscannedObjects" : 324, #扫描的对象
    "nscanned" : 324,        #扫描的索引数
    "nscannedObjectsAllPlans" : 324, #代表所有尝试执行的计划所扫描的对象
    "nscannedAllPlans" : 324,        #代表所有尝试执行的计划所扫描的索引
    "scanAndOrder" : false,          #True:对文档进行排序,false:对索引进行排序
    "indexOnly" : false,             #对查询的结果进行排序不需要搜索其他文档,查询和返回字段使用同一索引
    "nYields" : 0,                   #为了让写操作执行而让出读锁的次数
    "nChunkSkips" : 0,               #忽略文档数
    "millis" : 1,                    #执行查询消耗的时间
    "indexBounds" : {   #索引扫描中使用的最大/小值。
        "b" : [
            [
                "CYHS1301942",
                "CYHS1301942"
            ]
        ],
        "date" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ]
    },
    "server" : "db-mongo1:27017"
}

3.0之后:在explain()里有三个参数:"queryPlanner", "executionStats", and "allPlansExecution",默认是:queryPlanner。具体的含义见官方文档。

zjy:PRIMARY> db.newtask.find({"b":"CYHS1301942"}).explain()
{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "cde.newtask",    #集合
        "indexFilterSet" : false,
        "parsedQuery" : {
            "b" : {
                "$eq" : "CYHS1301942"
            }
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "IXSCAN",     #索引扫描,COLLSCAN表示全表扫描。
                "keyPattern" : {
                    "b" : 1,
                    "date" : 1
                },
                "indexName" : "b_1_date_1", #索引名
                "isMultiKey" : false,
                "direction" : "forward",
                "indexBounds" : {
                    "b" : [
                        "[\"CYHS1301942\", \"CYHS1301942\"]"
                    ],
                    "date" : [
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : [ ]
    },
    "serverInfo" : {
        "host" : "mongo1",
        "port" : 27017,
        "version" : "3.0.4",
        "gitVersion" : "0481c958daeb2969800511e7475dc66986fa9ed5"
    },
    "ok" : 1
}

3.0要是查看更详细的执行计划请看其他2个参数:

技术分享
zjy:PRIMARY> db.newtask.find({"b":"CYHS1301942"}).explain("allPlansExecution")
{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "cde.newtask",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "b" : {
                "$eq" : "CYHS1301942"
            }
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "b" : 1,
                    "date" : 1
                },
                "indexName" : "b_1_date_1",
                "isMultiKey" : false,
                "direction" : "forward",
                "indexBounds" : {
                    "b" : [
                        "[\"CYHS1301942\", \"CYHS1301942\"]"
                    ],
                    "date" : [
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : [ ]
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 1,
        "executionTimeMillis" : 0,
        "totalKeysExamined" : 1,
        "totalDocsExamined" : 1,
        "executionStages" : {
            "stage" : "FETCH",
            "nReturned" : 1,
            "executionTimeMillisEstimate" : 0,
            "works" : 2,
            "advanced" : 1,
            "needTime" : 0,
            "needFetch" : 0,
            "saveState" : 0,
            "restoreState" : 0,
            "isEOF" : 1,
            "invalidates" : 0,
            "docsExamined" : 1,
            "alreadyHasObj" : 0,
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : 1,
                "executionTimeMillisEstimate" : 0,
                "works" : 2,
                "advanced" : 1,
                "needTime" : 0,
                "needFetch" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "keyPattern" : {
                    "b" : 1,
                    "date" : 1
                },
                "indexName" : "b_1_date_1",
                "isMultiKey" : false,
                "direction" : "forward",
                "indexBounds" : {
                    "b" : [
                        "[\"CYHS1301942\", \"CYHS1301942\"]"
                    ],
                    "date" : [
                        "[MinKey, MaxKey]"
                    ]
                },
                "keysExamined" : 1,
                "dupsTested" : 0,
                "dupsDropped" : 0,
                "seenInvalidated" : 0,
                "matchTested" : 0
            }
        },
        "allPlansExecution" : [ ]
    },
    "serverInfo" : {
        "host" : "mongo1",
        "port" : 27017,
        "version" : "3.0.4",
        "gitVersion" : "0481c958daeb2969800511e7475dc66986fa9ed5"
    },
    "ok" : 1
}
View Code 技术分享
zjy:PRIMARY> db.newtask.find({"b":"CYHS1301942"}).explain("executionStats")
{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "cde.newtask",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "b" : {
                "$eq" : "CYHS1301942"
            }
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "b" : 1,
                    "date" : 1
                },
                "indexName" : "b_1_date_1",
                "isMultiKey" : false,
                "direction" : "forward",
                "indexBounds" : {
                    "b" : [
                        "[\"CYHS1301942\", \"CYHS1301942\"]"
                    ],
                    "date" : [
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : [ ]
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 1,
        "executionTimeMillis" : 0,
        "totalKeysExamined" : 1,
        "totalDocsExamined" : 1,
        "executionStages" : {
            "stage" : "FETCH",
            "nReturned" : 1,
            "executionTimeMillisEstimate" : 0,
            "works" : 2,
            "advanced" : 1,
            "needTime" : 0,
            "needFetch" : 0,
            "saveState" : 0,
            "restoreState" : 0,
            "isEOF" : 1,
            "invalidates" : 0,
            "docsExamined" : 1,
            "alreadyHasObj" : 0,
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : 1,
                "executionTimeMillisEstimate" : 0,
                "works" : 2,
                "advanced" : 1,
                "needTime" : 0,
                "needFetch" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "keyPattern" : {
                    "b" : 1,
                    "date" : 1
                },
                "indexName" : "b_1_date_1",
                "isMultiKey" : false,
                "direction" : "forward",
                "indexBounds" : {
                    "b" : [
                        "[\"CYHS1301942\", \"CYHS1301942\"]"
                    ],
                    "date" : [
                        "[MinKey, MaxKey]"
                    ]
                },
                "keysExamined" : 1,
                "dupsTested" : 0,
                "dupsDropped" : 0,
                "seenInvalidated" : 0,
                "matchTested" : 0
            }
        }
    },
    "serverInfo" : {
        "host" : "mongo1",
        "port" : 27017,
        "version" : "3.0.4",
        "gitVersion" : "0481c958daeb2969800511e7475dc66986fa9ed5"
    },
    "ok" : 1
}
View Code

上面介绍了如何查看执行计划,那么下面介绍下如何管理索引。

索引管理,具体请看[权威指南第5章]

1)查看/显示集合的索引:db.collectionName.getIndexes()或则db.system.indexes.find()

zjy:PRIMARY> db.data.getIndexes()
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",       #索引名
        "ns" : "survey.data"   #集合名
    },
    {
        "v" : 1,
        "unique" : true,       #唯一索引
        "key" : {
            "sid" : 1,
            "user" : 1
        },
        "name" : "sid_1_user_1",
        "ns" : "survey.data"
    },
    {
        "v" : 1,
        "key" : {
            "sid" : 1,
            "cdate" : -1
        },
        "name" : "sid_1_cdate_-1",
        "ns" : "survey.data"
    },
    {
        "v" : 1,
        "key" : {
            "sid" : 1,
            "created" : -1
        },
        "name" : "sid_1_created_-1",
        "ns" : "survey.data"
    },
    {
        "v" : 1,
        "key" : {
            "sid" : 1,
            "user" : 1,
            "modified" : 1
        },
        "name" : "sid_1_user_1_modified_1",
        "ns" : "survey.data"
    }
]
zjy:PRIMARY> db.system.indexes.find({"ns":"survey.data"})
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "survey.data" }
{ "v" : 1, "unique" : true, "key" : { "sid" : 1, "user" : 1 }, "name" : "sid_1_user_1", "ns" : "survey.data" }
{ "v" : 1, "key" : { "sid" : 1, "cdate" : -1 }, "name" : "sid_1_cdate_-1", "ns" : "survey.data" }
{ "v" : 1, "key" : { "sid" : 1, "created" : -1 }, "name" : "sid_1_created_-1", "ns" : "survey.data" }
{ "v" : 1, "key" : { "sid" : 1, "user" : 1, "modified" : 1 }, "name" : "sid_1_user_1_modified_1", "ns" : "survey.data" }

2)创建索引:db.collections.ensureIndex({...})

普通索引

zjy:PRIMARY> db.comments.ensureIndex({"name":1})  #name字段上创建索引,升序。倒序为-1。
{
    "createdCollectionAutomatically" : false,
                     

人气教程排行