Spring Data MongoDB Slow MongoTemplate.find() Performance

青春壹個敷衍的年華 提交于 2021-02-09 09:57:38

问题


I'm having performance issues when querying ~12,000 user documents, indexed by 1 column, (companyId), no other filter. The whole collection only has ~27000. It took me about 12 seconds to get the ~12000 rows of data...

I tried running explain for this query: db.instoreMember.find({companyId:"5b6be3e2096abd567974f924"}).explain();

result follows:

{
    "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
}

It seems that it is actually using the indexed companyId field, and if i do the search directly via mongodb shell, it's very fast: only 1~2 seconds.

But via Spring MongoDB Data - MongoTemplate:

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

This becomes very slow ~10-12seconds. (How i measure is that I put a break point at the find statement, let it step through to next line, which took about ~10-12seconds)

I've added the DEBUG line for mongodb spring bootstrap and here is the logged output of the find statement :

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

Version of spring-data-mongodb i use:

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

回答1:


I had this problem.

The slow part is mapping Document to Java object. Mongo template doesn't map at the codec level so it goes bson->Document->POJO. If you use just the mongo driver with the POJO codec that will go bson->pojo and remove the template mapping layer overhead.

Also, if you have old data and have moved packages, this will also break their mapping layer and make it super slow as it falls back to reflection.




回答2:


How do i see the raw query that is actually being executed by spring mongodb data?

If the query is taking 12 seconds to load, you actually have time to run db.currentOp to see what is taking so long. The output will contain 'command' field that you can use to see what the DB has been tasked with.




回答3:


To see the raw query being executed you can update the log level of the mongodb driver dependency to debug level. This should log the query to your log file.



来源:https://stackoverflow.com/questions/51836490/spring-data-mongodb-slow-mongotemplate-find-performance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!