首先從業務角度出發,不必要的篩選條件和粗略的篩選條件會嚴重影響查詢速度,比如 $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.
Refer:MongoDB適用場景