@Quieteroks
php программист

Как ускорить count запрос в mongodb?

Подскажите, что можно сделать с такой проблемой.
Имеется составной индекс по трем полям ИНН, ЕГРН и СТАТУС. В базе записей более миллиона с одинаковыми данными по индексу. Выборка 50 записей проходит моментально, но для пагинации требуется подсчет количества записей, подсчет количества записей в курсоре происходит на столько долго, что отваливается по таймауту в 30 секунд.

Почему монга не считает записи по индексу? И как ее заставить это сделать?
Может имеется какой-нибудь джедайский прием подсчета в обход функции count?

Explain запроса:
{
    "queryPlanner" : {
        "plannerVersion" : NumberInt(1),
        "namespace" : "db.history",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "$and" : [
                {
                    "source.egrul" : {
                        "$eq" : "1111111111111"
                    }
                },
                {
                    "source.inn" : {
                        "$eq" : "6111111111"
                    }
                },
                {
                    "$not" : {
                        "status" : {
                            "$eq" : NumberInt(-100)
                        }
                    }
                }
            ]
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "filter" : {
                "$and" : [
                    {
                        "$not" : {
                            "status" : {
                                "$eq" : NumberInt(-100)
                            }
                        }
                    },
                    {
                        "source.inn" : {
                            "$eq" : "6111111111"
                        }
                    }
                ]
            },
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "source.egrul" : NumberInt(1),
                    "source.inn" : NumberInt(1),
                    "status" : NumberInt(1)
                },
                "indexName" : "request_list",
                "isMultiKey" : true,
                "direction" : "forward",
                "indexBounds" : {
                    "source.egrul" : [
                        "[\"1111111111111\", \"1111111111111\"]"
                    ],
                    "source.inn" : [
                        "[MinKey, MaxKey]"
                    ],
                    "status" : [
                        "[MinKey, -100)",
                        "(-100, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : [

        ]
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : NumberInt(578422),
        "executionTimeMillis" : NumberInt(3184),
        "totalKeysExamined" : NumberInt(578422),
        "totalDocsExamined" : NumberInt(578422),
        "executionStages" : {
            "stage" : "FETCH",
            "filter" : {
                "$and" : [
                    {
                        "$not" : {
                            "status" : {
                                "$eq" : NumberInt(-100)
                            }
                        }
                    },
                    {
                        "source.inn" : {
                            "$eq" : "6111111111"
                        }
                    }
                ]
            },
            "nReturned" : NumberInt(578422),
            "executionTimeMillisEstimate" : NumberInt(2930),
            "works" : NumberInt(578423),
            "advanced" : NumberInt(578422),
            "needTime" : NumberInt(0),
            "needFetch" : NumberInt(0),
            "saveState" : NumberInt(4519),
            "restoreState" : NumberInt(4519),
            "isEOF" : NumberInt(1),
            "invalidates" : NumberInt(0),
            "docsExamined" : NumberInt(578422),
            "alreadyHasObj" : NumberInt(0),
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : NumberInt(578422),
                "executionTimeMillisEstimate" : NumberInt(800),
                "works" : NumberInt(578423),
                "advanced" : NumberInt(578422),
                "needTime" : NumberInt(0),
                "needFetch" : NumberInt(0),
                "saveState" : NumberInt(4519),
                "restoreState" : NumberInt(4519),
                "isEOF" : NumberInt(1),
                "invalidates" : NumberInt(0),
                "keyPattern" : {
                    "source.egrul" : NumberInt(1),
                    "source.inn" : NumberInt(1),
                    "status" : NumberInt(1)
                },
                "indexName" : "request_list",
                "isMultiKey" : true,
                "direction" : "forward",
                "indexBounds" : {
                    "source.egrul" : [
                        "[\"1111111111111\", \"1111111111111\"]"
                    ],
                    "source.inn" : [
                        "[MinKey, MaxKey]"
                    ],
                    "status" : [
                        "[MinKey, -100)",
                        "(-100, MaxKey]"
                    ]
                },
                "keysExamined" : NumberInt(578422),
                "dupsTested" : NumberInt(578422),
                "dupsDropped" : NumberInt(0),
                "seenInvalidated" : NumberInt(0),
                "matchTested" : NumberInt(0)
            }
        },
        "allPlansExecution" : [

        ]
    },
    "serverInfo" : {
        "host" : "db.local",
        "port" : NumberInt(27017),
        "version" : "3.0.4",
        "gitVersion" : "0481c958daeb2969800511e7475dc66986fa9ed5"
    }
}
  • Вопрос задан
  • 626 просмотров
Пригласить эксперта
Ответы на вопрос 1
@lega
Наличие индекса не гарантирует его использование, профилируйте запрос, скорей всего индекс не работает (например если используете regex фильтр).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы