zoukankan      html  css  js  c++  java
  • [MongoDB] aggregate 查询的优化思路

    首先从业务角度出发,不必要的筛选条件和粗略的筛选条件会严重影响查询速度,比如 $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.

    Link:https://www.cnblogs.com/farwish/p/15379066.html

  • 相关阅读:
    haproxy教程
    haproxy和keepalived的理解(转载)
    redis集群搭建_超详细
    磁盘IO过高时的参考
    tomcat优化
    MYSQL数据库的主从复制
    k8s学习笔记-etcd介绍和集群搭建
    python排序算法二---冒泡排序
    Python排序算法一—快速排序
    python:如何判断字典a在字典b
  • 原文地址:https://www.cnblogs.com/farwish/p/15379066.html
Copyright © 2011-2022 走看看