Низкая производительность при использовании $ lte и $ gte MongoDB - PullRequest
0 голосов
/ 14 мая 2018

В настоящее время я работаю с 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")

Я получил ответ в течение 5 секунд, когда он проверяет только ключи 955043.

Вот ответ с включенной опцией объяснения:

{
    "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 мс.

Я ожидал, что Монго ответит до 100 мс, но я не уверен, что здесь будет не так.

Любая идея великолепна, спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...