使用$ lte和$ gte MongoDB的性能不佳

时间:2018-05-14 18:06:01

标签: c# mongodb performance mongoose mongodb-query

我目前正在使用MongoDB 3.6.1,并且我使用复合索引面临一种奇怪的行为。我有一个包含大约2百万个文档的集合,这是一个文档的结构:

{
"_id" : ObjectId("5af478b408e0f42946ff14ec"),
"IpStart" : NumberLong(50331649),
"IpEnd" : NumberLong(54525951),
"Latitude" : "47.634",
"Longitude" : "-122.342",
"PostalCode" : "98109",
"MarketId" : 308,
"City" : "Seattle",
"State" : "WA"
}

我的索引看起来像:

[
        {
            "v" : 2,
            "key" : {
                "_id" : 1
            },
            "name" : "_id_",
            "ns" : "locations_fact.IpRangeLocations"
        },
        {
            "v" : 2,
            "unique" : true,
            "key" : {
                "IpStart" : 1,
                "IpEnd" : 1
            },
            "name" : "IpStart_1_IpEnd_1",
            "ns" : "locations_fact.IpRangeLocations"
        }
]

当我提出这个问题时:

db.IpRangeLocations.find({"IpStart":{$lt:1209192009}, "IpEnd":{$gt:1209192009}}).explain("executionStats")

当我只检查955043键时,我得到了5秒的响应。

以下是解释选项启用的响应:

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "locations_fact.IpRangeLocations",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "$and" : [ 
                {
                    "IpStart" : {
                        "$lt" : 1209192009.0
                    }
                }, 
                {
                    "IpEnd" : {
                        "$gt" : 1209192009.0
                    }
                }
            ]
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "IpStart" : 1,
                    "IpEnd" : 1
                },
                "indexName" : "IpStart_1_IpEnd_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "IpStart" : [],
                    "IpEnd" : []
                },
                "isUnique" : true,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "IpStart" : [ 
                        "[-inf.0, 1209192009.0)"
                    ],
                    "IpEnd" : [ 
                        "(1209192009.0, inf.0]"
                    ]
                }
            }
        },
        "rejectedPlans" : []
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 1,
        "executionTimeMillis" : 5019,
        "totalKeysExamined" : 955043,
        "totalDocsExamined" : 1,
        "executionStages" : {
            "stage" : "FETCH",
            "nReturned" : 1,
            "executionTimeMillisEstimate" : 4823,
            "works" : 955043,
            "advanced" : 1,
            "needTime" : 955041,
            "needYield" : 0,
            "saveState" : 7530,
            "restoreState" : 7530,
            "isEOF" : 1,
            "invalidates" : 0,
            "docsExamined" : 1,
            "alreadyHasObj" : 0,
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : 1,
                "executionTimeMillisEstimate" : 4773,
                "works" : 955043,
                "advanced" : 1,
                "needTime" : 955041,
                "needYield" : 0,
                "saveState" : 7530,
                "restoreState" : 7530,
                "isEOF" : 1,
                "invalidates" : 0,
                "keyPattern" : {
                    "IpStart" : 1,
                    "IpEnd" : 1
                },
                "indexName" : "IpStart_1_IpEnd_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "IpStart" : [],
                    "IpEnd" : []
                },
                "isUnique" : true,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "IpStart" : [ 
                        "[-inf.0, 1209192009.0)"
                    ],
                    "IpEnd" : [ 
                        "(1209192009.0, inf.0]"
                    ]
                },
                "keysExamined" : 955043,
                "seeks" : 955042,
                "dupsTested" : 0,
                "dupsDropped" : 0,
                "seenInvalidated" : 0
            }
        }
    },
    "serverInfo" : {
        "host" : "SOLANOD",
        "port" : 27017,
        "version" : "3.6.1",
        "gitVersion" : "025d4f4fe61efd1fb6f0005be20cb45a004093d1"
    },
    "ok" : 1.0
}

然后当我删除复合索引时,我得到了更好的结果(1.932秒),但它检查了1726879个文档(更多的是使用索引)

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "locations_fact.IpRangeLocations",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "$and" : [ 
                {
                    "IpStart" : {
                        "$lt" : 1209192009.0
                    }
                }, 
                {
                    "IpEnd" : {
                        "$gt" : 1209192009.0
                    }
                }
            ]
        },
        "winningPlan" : {
            "stage" : "COLLSCAN",
            "filter" : {
                "$and" : [ 
                    {
                        "IpStart" : {
                            "$lt" : 1209192009.0
                        }
                    }, 
                    {
                        "IpEnd" : {
                            "$gt" : 1209192009.0
                        }
                    }
                ]
            },
            "direction" : "forward"
        },
        "rejectedPlans" : []
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 1,
        "executionTimeMillis" : 1916,
        "totalKeysExamined" : 0,
        "totalDocsExamined" : 1726879,
        "executionStages" : {
            "stage" : "COLLSCAN",
            "filter" : {
                "$and" : [ 
                    {
                        "IpStart" : {
                            "$lt" : 1209192009.0
                        }
                    }, 
                    {
                        "IpEnd" : {
                            "$gt" : 1209192009.0
                        }
                    }
                ]
            },
            "nReturned" : 1,
            "executionTimeMillisEstimate" : 1697,
            "works" : 1726881,
            "advanced" : 1,
            "needTime" : 1726879,
            "needYield" : 0,
            "saveState" : 13531,
            "restoreState" : 13531,
            "isEOF" : 1,
            "invalidates" : 0,
            "direction" : "forward",
            "docsExamined" : 1726879
        }
    },
    "serverInfo" : {
        "host" : "SOLANOD",
        "port" : 27017,
        "version" : "3.6.1",
        "gitVersion" : "025d4f4fe61efd1fb6f0005be20cb45a004093d1"
    },
    "ok" : 1.0
}

此外,我尝试创建单独的索引(一个用于IpStart,另一个用于IpEnd),但没有任何改进。

当我使用语句和复合索引对SQL进行相同的查询时:

SELECT * FROM [dbo].[ip_range_location] WHERE ipaddress BETWEEN ip_start AND ip_end

它不会超过300毫秒。

我期待Mongo会在100毫秒内回答,但我不确定这里会出现什么问题。

任何想法都很棒,谢谢

0 个答案:

没有答案