首先从业务角度出发,不必要的筛选条件和粗略的筛选条件会严重影响查询速度,比如 $or 查询和 $in 查询,视情况尽可能去掉。
程序中打印出查询条件的各部分,有 $match、$group。比如 PHP 中可以通过 var_export()。
由于 aggregate 执行主要是 pipeline 步骤,所以着重需要关注的是 $match 条件。
打印出的数组 json_encode 后可以在 Robo3T 等客户端中作为 aggregate 的条件使用。
关于 aggregate 查询条件的格式,可参考:https://studio3t.com/knowledge-base/articles/build-mongodb-aggregation-queries/
为了方便查看 json 条件格式,可以对json在线格式化,之后使用如 Example1.
aggregate() 后面直接带不了 explain() 方法,为了使用 explain() 方法查看索引使用情况等信息,复制出 $match 的 json 条件 到 find({ }) 中,然后带上 explain() 方法。
查看 explain() 显示的信息 queryPlanner 部分,里面有 winningPlan.stage 状态分析,如 Example2.
常见的 winningPlan.stage 如下:
COLLSCAN:全表扫描
IXSCAN :索引扫描
FETCH :根据索引去检索指定document
更多的可以搜索 mongodb explain 相关信息。
把 COLLSCAN 优化成 IXSCAN 使用索引,此时再看 winningPlan.inputStage.keyPattern 使用的索引字段是哪个。
如果 keyPattern 使用的是低效率的索引可以通过 hint 用法强制指定索引,支持普通查询和聚合查询。
普通查询的 hint 方法: ->find({})->hint({ diff_id: 1 })
聚合查询的 hint 参数:docs.mongodb.com,如 Example3.
Example1.
db.getCollection('diff_detail').aggregate( [ { "$match": { "diff_id": ObjectId('71162dcf17a1f594edcc69bc'), "pvalue": { "$lt": 0.05 }, "vip": { "$gt": 1 }, "$or": [{ "fc": { "$gt": 1 } }, { "fc": { "$lt": 1 } }], "diff_group": { "$in": ["a1_vs_A1", "a2_vs_A2", "a3_vs_A3", "a4_vs_A4", "a5_vs_A5"] } } }, { "$group": { "_id": { "table_type": "$table_type", "diff_group": "$diff_group" }, "count": { "$sum": 1 } } } ] );
Example2.
{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "xxxdb.diff_detail", "indexFilterSet" : false, "parsedQuery" : { "$and" : [ { "$or" : [ { "fc" : { "$lt" : 1.0 } }, { "fc" : { "$gt" : 1.0 } } ] }, { "diff_id" : { "$eq" : ObjectId("71162dcf17a1f594edcc69bc") } }, { "pvalue" : { "$lt" : 0.05 } }, { "vip" : { "$gt" : 1.0 } }, { "diff_group" : { "$in" : [ "a1_vs_A1", "a2_vs_A2", "a3_vs_A3", "a4_vs_A4", "a5_vs_A5" ] } } ] }, "queryHash" : "22D09A47", "planCacheKey" : "22D09A47", "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "$and" : [ { "$or" : [ { "fc" : { "$lt" : 1.0 } }, { "fc" : { "$gt" : 1.0 } } ] }, { "diff_id" : { "$eq" : ObjectId("71162dcf17a1f594edcc69bc") } }, { "pvalue" : { "$lt" : 0.05 } }, { "vip" : { "$gt" : 1.0 } }, { "diff_group" : { "$in" : [ "a1_vs_A1", "a2_vs_A2", "a3_vs_A3", "a4_vs_A4", "a5_vs_A5" ] } } ] }, "direction" : "forward" }, "rejectedPlans" : [] }, "serverInfo" : { "host" : "mongodb446", "port" : 27017, "version" : "4.4.1", "gitVersion" : "ad91a93a5a31e175f5cbf8c69561e788bbc55ce1" }, "ok" : 1.0 }
Example3.