Spring Data MongoDB Медленная производительность MongoTemplate.find ()

У меня проблемы с производительностью при запросе ~ 12 000 пользовательских документов, индексированных по 1 столбцу (companyId), без другого фильтра. Всего в коллекции всего ~ 27000. Мне потребовалось около 12 секунд, чтобы получить ~ 12000 строк данных ...

Я попытался запустить объяснение для этого запроса: db.instoreMember.find ({companyId: "5b6be3e2096abd567974f924"}). Объяснять ();

результат следующий:

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "production.instoreMember",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "companyId" : {
                "$eq" : "5b6be3e2096abd567974f924"
            }
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "companyId" : 1,
                    "name" : 1,
                    "phoneNumber" : 1
                },
                "indexName" : "companyId_1_name_1_phoneNumber_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "companyId" : [ ],
                    "name" : [ ],
                    "phoneNumber" : [ ]
                },
                "isUnique" : true,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "companyId" : [
                        "[\"5b6be3e2096abd567974f924\", \"5b6be3e2096abd567974f924\"]"
                    ],
                    "name" : [
                        "[MinKey, MaxKey]"
                    ],
                    "phoneNumber" : [
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : [
            {
                "stage" : "FETCH",
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "companyId" : 1
                    },
                    "indexName" : "companyId_1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "companyId" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "companyId" : [
                            "[\"5b6be3e2096abd567974f924\", \"5b6be3e2096abd567974f924\"]"
                        ]
                    }
                }
            }
        ]
    },
    "serverInfo" : {

    },
    "ok" : 1
}

Кажется, что он на самом деле использует индексированное поле companyId, и если я выполняю поиск напрямую через оболочку mongodb, это очень быстро: всего 1-2 секунды.

Но через данные Spring MongoDB - MongoTemplate:

final Query query = new Query().addCriteria(Criteria.where("companyId").is(adminCompanyId));
final List<InstoreMember> listOfInstoreMembers = mongoTemplate.find(query, InstoreMember.class);

Это становится очень медленным ~ 10-12 секунд. (Как я измеряю, так это то, что я помещаю точку останова в оператор find, позволяя ему перейти к следующей строке, что заняло около 10-12 секунд)

Я добавил строку DEBUG для начальной загрузки mongodb spring, и вот записанный вывод оператора find:

2018-08-14 23:53:34.493 DEBUG 22733 --- [bio-8080-exec-2] o.s.data.mongodb.core.MongoTemplate      : 
find using query: { "companyId" : "58fa36dd31d103038e64b061"} fields: null for class: class fn.model.InstoreMember in collection: instoreMember

Версия spring-data-mongodb, которую я использую:

compile ("org.springframework.data:spring-data-mongodb:1.10.7.RELEASE")

person user1955934    schedule 14.08.2018    source источник
comment
Не могли бы вы опубликовать образцы кода и документов? При таком объеме информации практически невозможно угадать, в чем проблема ...   -  person dnickless    schedule 14.08.2018
comment
Я добавил результаты объяснения запроса выше   -  person user1955934    schedule 14.08.2018
comment
Если вы используете Spring Boot, добавьте это в application.properties и опубликуйте результат logging.level.org.springframework.data.mongodb.core.MongoTemplate = DEBUG   -  person Marco    schedule 14.08.2018
comment
Проверьте это, чтобы регистрировать все запросы: stackoverflow.com/a/29849568/6440033   -  person dnickless    schedule 14.08.2018
comment
Как вы меряли 12? Сам запрос не может быть таким медленным, если у вас не очень медленно вращающийся диск или какая-то сверхмедленная сеть ...   -  person dnickless    schedule 14.08.2018
comment
Я просто поместил отладочную инструкцию в mongoTemplate.find, запустил ее, подождал ~ 12 секунд, и тогда он остановился бы на следующей строке ..   -  person user1955934    schedule 14.08.2018
comment
Я думаю, что мой запрос довольно простой, я не понимаю, почему он так сильно отличается от выполнения запроса с использованием клиента командной строки mongodb ..   -  person user1955934    schedule 14.08.2018
comment
Марко: Я добавил результаты журнала, добавив эту строку отладки в application.properties. Кажется, что запрос правильный, но он все еще очень медленный. Я так застрял   -  person user1955934    schedule 14.08.2018


Ответы (3)


У меня была такая проблема.

Медленная часть - это отображение документа на объект Java. Шаблон Mongo не отображается на уровне кодека, поэтому он выглядит как bson-> Document-> POJO. Если вы используете только драйвер mongo с кодеком POJO, который перейдет в bson-> pojo и удалит накладные расходы на слой сопоставления шаблонов.

Кроме того, если у вас есть старые данные и вы переместили пакеты, это также нарушит их слой сопоставления и сделает его очень медленным, поскольку он возвращается к отражению.

person Bob    schedule 16.05.2019

Как я могу увидеть необработанный запрос, который на самом деле выполняется данными Spring mongodb?

Если запрос загружается 12 секунд, у вас действительно есть время запустить db .currentOp, чтобы узнать, что занимает так много времени. Вывод будет содержать поле «команда», которое вы можете использовать, чтобы увидеть, с чем была поставлена ​​задача БД.

person Tony Sepia    schedule 14.08.2018
comment
{inprog: [], ok: 1, operationTime: Timestamp (1534265282, 6)} Это дает мне указанное выше, когда он тратит время на шаг mongoTemplate.find () - person user1955934; 14.08.2018
comment
@ user1955934 Я думаю, это может означать, что, когда он «не торопится», он не запрашивает БД. Можете ли вы перейти к утверждению, чтобы еще больше выделить причину ожидания? - person Tony Sepia; 15.08.2018
comment
но это код MongoTemplate. Это очень простой запрос .find, я бы не ожидал, что проблема будет в библиотеке ... хотя это возможно ..? - person user1955934; 15.08.2018
comment
@ user1955934 выполните их код, если можете, так как похоже, что вы хотите узнать, что происходит внутри - person Tony Sepia; 15.08.2018
comment
это другой случай, если мой запрос особенный / уникальный, я, вероятно, попытаюсь выяснить, что происходит с библиотекой. Но это действительно, почти привет мир библиотеки ... я имею в виду, давай, я уверен, что тысячи людей используют эту библиотеку, она точно не потерпит неудачу в самом простом поисковом запросе? Я могу что-то пропустить или неправильно использую, надеюсь, кто-то сможет указать на это - person user1955934; 16.08.2018

Чтобы увидеть выполняемый необработанный запрос, вы можете обновить уровень журнала зависимости драйвера mongodb до уровня отладки. Это должно записать запрос в ваш файл журнала.

person Rishabh Agarwal    schedule 14.08.2018
comment
Вы также можете проверить репозиторий git драйвера mongodb github.com/spring-projects/spring -data-mongodb. Учитывая, что вы используете: ‹groupId› org.springframework.data ‹/groupId› ‹artifactId› spring-data-mongodb ‹/artifactId› - person Rishabh Agarwal; 14.08.2018