最近遇到个mongo慢查问题,查询这样子:

db.tb1.find({status:'normal', lastReviewTime:{$gte:1583038740,$lte:1585285140}}).sort({createdTime:-1}).limit(30)


执行计划如下:

> db.tb1.find({status:'normal', lastReviewTime:{$gte:1583038740,$lte:1585285140}}).sort({createdTime:-1}).limit(30).explain()
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "db1.tb1",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "$and" : [
                                {
                                        "status" : {
                                                "$eq" : "normal"
                                        }
                                },
                                {
                                        "lastReviewTime" : {
                                                "$lte" : 1585285140
                                        }
                                },
                                {
                                        "lastReviewTime" : {
                                                "$gte" : 1583038740
                                        }
                                }
                        ]
                },
                "winningPlan" : {
                        "stage" : "SORT",
                        "sortPattern" : {
                                "createdTime" : -1
                        },
                        "limitAmount" : 30,
                        "inputStage" : {
                                "stage" : "SORT_KEY_GENERATOR",
                                "inputStage" : {
                                        "stage" : "FETCH",
                                        "filter" : {
                                                "$and" : [
                                                        {
                                                                "lastReviewTime" : {
                                                                        "$lte" : 1585285140
                                                                }
                                                        },
                                                        {
                                                                "lastReviewTime" : {
                                                                        "$gte" : 1583038740
                                                                }
                                                        }
                                                ]
                                        },
                                        "inputStage" : {
                                                "stage" : "IXSCAN",
                                                "keyPattern" : {
                                                        "status" : 1,
                                                        "type" : 1,
                                                        "executionTime" : 1
                                                },
                                                "indexName" : "idx_stats_typ_execTime",   # 走的这个索引
                                                "isMultiKey" : false,
                                                "multiKeyPaths" : {
                                                        "status" : [ ],
                                                        "type" : [ ],
                                                        "executionTime" : [ ]
                                                },
                                                "isUnique" : false,
                                                "isSparse" : false,
                                                "isPartial" : false,
                                                "indexVersion" : 2,
                                                "direction" : "forward",
                                                "indexBounds" : {
                                                        "status" : [
                                                                "[\"normal\", \"normal\"]"
                                                        ],
                                                        "type" : [
                                                                "[MinKey, MaxKey]"
                                                        ],
                                                        "executionTime" : [
                                                                "[MinKey, MaxKey]"
                                                        ]
                                                }
                                        }
                                }
                        }
                },
                "rejectedPlans" : [
                        {
                                "stage" : "SORT",
                                "sortPattern" : {
                                        "createdTime" : -1
                                },
                                "limitAmount" : 30,
                                "inputStage" : {
                                        "stage" : "SORT_KEY_GENERATOR",
                                        "inputStage" : {
                                                "stage" : "FETCH",
                                                "inputStage" : {
                                                        "stage" : "IXSCAN",
                                                        "keyPattern" : {
                                                                "lastReviewTime" : 1,
                                                                "status" : 1,
                                                                "createdTime" : -1
                                                        },
                                                        "indexName" : "lastReviewTime_1_status_1_createdTime_-1",
                                                        "isMultiKey" : false,
                                                        "multiKeyPaths" : {
                                                                "lastReviewTime" : [ ],
                                                                "status" : [ ],
                                                                "createdTime" : [ ]
                                                        },
                                                        "isUnique" : false,
                                                        "isSparse" : false,
                                                        "isPartial" : false,
                                                        "indexVersion" : 2,
                                                        "direction" : "forward",
                                                        "indexBounds" : {
                                                                "lastReviewTime" : [
                                                                        "[1583038740.0, 1585285140.0]"
                                                                ],
                                                                "status" : [
                                                                        "[\"normal\", \"normal\"]"
                                                                ],
                                                                "createdTime" : [
                                                                        "[MaxKey, MinKey]"
                                                                ]
                                                        }
                                                }
                                        }
                                }
                        },
                        {
                                "stage" : "SORT",
                                "sortPattern" : {
                                        "createdTime" : -1
                                },
                                "limitAmount" : 30,
                                "inputStage" : {
                                        "stage" : "SORT_KEY_GENERATOR",
                                        "inputStage" : {
                                                "stage" : "FETCH",
                                                "inputStage" : {
                                                        "stage" : "IXSCAN",
                                                        "keyPattern" : {
                                                                "lastReviewTime" : -1,
                                                                "status" : 1
                                                        },
                                                        "indexName" : "lastReviewTime_-1_status_1",
                                                        "isMultiKey" : false,
                                                        "multiKeyPaths" : {
                                                                "lastReviewTime" : [ ],
                                                                "status" : [ ]
                                                        },
                                                        "isUnique" : false,
                                                        "isSparse" : false,
                                                        "isPartial" : false,
                                                        "indexVersion" : 2,
                                                        "direction" : "forward",
                                                        "indexBounds" : {
                                                                "lastReviewTime" : [
                                                                        "[1585285140.0, 1583038740.0]"
                                                                ],
                                                                "status" : [
                                                                        "[\"normal\", \"normal\"]"
                                                                ]
                                                        }
                                                }
                                        }
                                }
                        }
                ]
        },
        "ok" : 1
}


这种情况下,我们的索引顺序需要注意下,这样写:

{精确匹配字段,排序字段,范围查询字段} 这样的索引排序会更为高效

db.tb1.createIndex({status:1,createdTime:-1,lastReviewTime:1},{background:true})


加完索引后,可以发现查询速度有质的飞越了。