如何使用日期时间范围优化此mongoDB Agregation

时间:2015-06-11 09:05:11

标签: performance mongodb optimization

当我尝试在mongoDB 3.0.3中使用日期范围时,我遇到了一个非常慢的聚合命令的问题

首先是一些背景:

有问题的收集来自VoIP系统的CDR(呼叫详细记录)。目前有337988521条记录,但我的查询只涉及一小部分。以下是了解范围的计数:

db.CDRs.find({"Date" : { $gte : new Date("2015-06-10T07:00:00Z") } }).count()
116114
db.CDRs.find({"Date" : { $gte : new Date("2015-06-10T08:00:00Z") } }).count()
0

以下是我的索引:

    {
            "v" : 1,
            "key" : {
                    "_id" : 1
            },
            "name" : "_id_",
            "ns" : "HS4XC.CDRs"
    },
    {
            "v" : 1,
            "unique" : true,
            "key" : {
                    "Date" : 1,
                    "CallID" : 1,
                    "TerminationAttempts.Attempt" : 1
            },
            "name" : "Date_1_CallID_1_TerminationAttempts.Attempt_1",
            "ns" : "HS4XC.CDRs"
    },
    {
            "v" : 1,
            "key" : {
                    "Originator" : 1,
                    "TerminationAttempts.Terminator" : 1
            },
            "name" : "Originator_1_TerminationAttempts.Terminator_1",
            "ns" : "HS4XC.CDRs"
    },
    {
            "v" : 1,
            "key" : {
                    "TerminationAttempts.Terminator" : 1,
                    "Originator" : 1
            },
            "name" : "TerminationAttempts.Terminator_1_Originator_1",
            "ns" : "HS4XC.CDRs"
    }

所以你可以看到我在Date对象上有一个索引。

以下是集合中的示例文档(公司数据被遮挡):

{
    "_id" : ObjectId("5577e072e988475f14b9a159"),
    "CallID" : "BW090000946100615-1715027548@XX.XX.XX.XX",
    "Date" : ISODate("2015-06-10T07:00:00Z"),
    "CallSetupTime" : NumberLong(36400),
    "CallPDD" : NumberLong(324),
    "TerminationAttempts" : [
            {
                    "TermID" : "1234",
                    "Attempt" : NumberLong(1),
                    "DisconnectReason" : "503",
                    "TermCallSetupTime" : NumberLong(324),
                    "Media" : "XC RTP Proxy2",
                    "RoutingGroupID" : "0",
                    "ToIP" : "XX.XX.XX.XX",
                    "TermSrcID" : "5",
                    "BsideIP" : "XX.XX.XX.XX",
                    "TermPDD" : NumberLong(324),
                    "Terminator" : "terminator_name",
                    "RoutingResponse" : "sip34655938784@XX.XX.XX.XX;orig=1896;rate=1071;term=9035;cost=1071;fed=2,467;cliValid=0;Spam-Score=0;Test-No=0",
                    "ModifyTS" : ISODate("2015-06-10T07:00:09Z"),
                    "RouteType" : "0"
            },
            {
                    "MatchedRoutingPrefix" : "346",
                    "TermCallSetupTime" : NumberLong(36075),
                    "Media" : "XC RTP Proxy2",
                    "TermSrcID" : "1",
                    "TermPDD" : NumberLong(3545),
                    "RingingType" : "D",
                    "RoutingResponse" : "sip34655938784@.XX.XX.XX.XX;orig=1896;rate=1071;term=9035;cost=1071;fed=2,467;cliValid=0;Spam-Score=0;Test-No=0",
                    "FinalToNumber" : "+555-555-5555",
                    "RouteType" : "0",
                    "TermID" : "7472",
                    "Attempt" : NumberLong(2),
                    "DisconnectReason" : "487",
                    "RoutingGroupID" : "56",
                    "ToIP" : "XX.XX.XX.XX",
                    "BsideIP" : "XX.XX.XX.XX",
                    "Terminator" : "terminator_name",
                    "ModifyTS" : ISODate("2015-06-10T07:00:48Z")
            }
    ],
    "LocationName" : "Spain",
    "OrigToNumber" : "+555-555-5555",
    "CreatorID" : "16120",
    "Authentication" : "XX.XX.XX.XX",
    "Aside" : "XC Opensips A Side",
    "UserID" : "GAA-Z",
    "Originator" : "Originator_name",
    "ToNumber" : "555-555-5555",
    "CountryID" : "807",
    "UserGroupID" : "1896",
    "LocationID" : "14530",
    "FederationID" : "0",
    "PDD" : NumberLong(9219)
}

因此,如果我运行此查询,则速度非常快:

db.CDRs.aggregate([
{$match: {"Date": {"$gte": new Date("2015-06-10T07:00:00Z")} } },
{$unwind: '$TerminationAttempts'},
{$group: {
    _id: {"Originator": "$Originator"}, 
    "minutes": {$sum: "$TerminationAttempts.Duration" }
}}
])

但如果我运行此查询则需要数小时

db.CDRs.aggregate([
{$match: {"Date": {"$gte": new Date("2015-06-10T07:00:00Z"), "$lt": new Date("2015-06-10T07:10:00Z") } } },
{$unwind: '$TerminationAttempts'},
{$group: {
    _id: {"Originator": "$Originator"}, 
    "minutes": {$sum: "$TerminationAttempts.Duration" }
}}
])

最后这里是慢查询的解释:

{
    "stages" : [
            {
                    "$cursor" : {
                            "query" : {
                                    "Date" : {
                                            "$gte" : ISODate("2015-06-10T07:00:00Z"),
                                            "$lt" : ISODate("2015-06-10T07:10:00Z")
                                    }
                            },
                            "fields" : {
                                    "Originator" : 1,
                                    "TerminationAttempts" : 1,
                                    "_id" : 0
                            },
                            "queryPlanner" : {
                                    "plannerVersion" : 1,
                                    "namespace" : "HS4XC.CDRs",
                                    "indexFilterSet" : false,
                                    "parsedQuery" : {
                                            "$and" : [
                                                    {
                                                            "Date" : {
                                                                    "$lt" : ISODate("2015-06-10T07:10:00Z")
                                                            }
                                                    },
                                                    {
                                                            "Date" : {
                                                                    "$gte" : ISODate("2015-06-10T07:00:00Z")
                                                            }
                                                    }
                                            ]
                                    },
                                    "winningPlan" : {
                                            "stage" : "KEEP_MUTATIONS",
                                            "inputStage" : {
                                                    "stage" : "FETCH",
                                                    "filter" : {
                                                            "Date" : {
                                                                    "$gte" : ISODate("2015-06-10T07:00:00Z")
                                                            }
                                                    },
                                                    "inputStage" : {
                                                            "stage" : "IXSCAN",
                                                            "keyPattern" : {
                                                                    "Date" : 1,
                                                                    "CallID" : 1,
                                                                    "TerminationAttempts.Attempt" : 1
                                                            },
                                                            "indexName" : "Date_1_CallID_1_TerminationAttempts.Attempt_1",
                                                            "isMultiKey" : true,
                                                            "direction" : "forward",
                                                            "indexBounds" : {
                                                                    "Date" : [
                                                                            "(true, new Date(1433920200000))"
                                                                    ],
                                                                    "CallID" : [
                                                                            "[MinKey, MaxKey]"
                                                                    ],
                                                                    "TerminationAttempts.Attempt" : [
                                                                            "[MinKey, MaxKey]"
                                                                    ]
                                                            }
                                                    }
                                            }
                                    },
                                    "rejectedPlans" : [ ]
                            }
                    }
            },
            {
                    "$unwind" : "$TerminationAttempts"
            },
            {
                    "$group" : {
                            "_id" : {
                                    "Originator" : "$Originator"
                            },
                            "minutes" : {
                                    "$sum" : "$TerminationAttempts.Duration"
                            }
                    }
            }
    ],
    "ok" : 1
}

帮助!

1 个答案:

答案 0 :(得分:0)

在添加了Date only索引之后,有一个新解释输出的请求。谢谢@ user3561036

{
    "stages" : [
            {
                    "$cursor" : {
                            "query" : {
                                    "Date" : {
                                            "$gte" : ISODate("2015-06-10T07:00:00Z"),
                                            "$lt" : ISODate("2015-06-10T07:10:00Z")
                                    }
                            },
                            "fields" : {
                                    "Originator" : 1,
                                    "TerminationAttempts" : 1,
                                    "_id" : 0
                            },
                            "queryPlanner" : {
                                    "plannerVersion" : 1,
                                    "namespace" : "HS4XC.CDRs",
                                    "indexFilterSet" : false,
                                    "parsedQuery" : {
                                            "$and" : [
                                                    {
                                                            "Date" : {
                                                                    "$lt" : ISODate("2015-06-10T07:10:00Z")
                                                            }
                                                    },
                                                    {
                                                            "Date" : {
                                                                    "$gte" : ISODate("2015-06-10T07:00:00Z")
                                                            }
                                                    }
                                            ]
                                    },
                                    "winningPlan" : {
                                            "stage" : "CACHED_PLAN",
                                            "inputStage" : {
                                                    "stage" : "FETCH",
                                                    "inputStage" : {
                                                            "stage" : "IXSCAN",
                                                            "keyPattern" : {
                                                                    "Date" : 1
                                                            },
                                                            "indexName" : "Date_1",
                                                            "isMultiKey" : false,
                                                            "direction" : "forward",
                                                            "indexBounds" : {
                                                                    "Date" : [
                                                                            "[new Date(1433919600000), new Date(1433920200000))"
                                                                    ]
                                                            }
                                                    }
                                            }
                                    },
                                    "rejectedPlans" : [ ]
                            }
                    }
            },
            {
                    "$unwind" : "$TerminationAttempts"
            },
            {
                    "$group" : {
                            "_id" : {
                                    "Originator" : "$Originator"
                            },
                            "minutes" : {
                                    "$sum" : "$TerminationAttempts.Duration"
                            }
                    }
            }
    ],
    "ok" : 1
}