Задать вопрос
@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"
    }
}
  • Вопрос задан
  • 663 просмотра
Подписаться 3 Оценить 1 комментарий
Помогут разобраться в теме Все курсы
  • Merion Academy
    MongoDB для разработчиков и DevOps
    4 месяца
    Далее
  • Нетология
    Разработчик на Python совместно с МФТИ
    7 месяцев
    Далее
  • Академия Эдюсон
    FullStack-разработчик: тариф PRO
    14 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 1
@lega
Наличие индекса не гарантирует его использование, профилируйте запрос, скорей всего индекс не работает (например если используете regex фильтр).
Ответ написан
Ваш ответ на вопрос

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

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