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

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

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