Mongodb 2.4 2dsphere queries very slow (using $geo

2019-09-09 09:54发布

问题:

mongod.log shows:

 {deliver_area: { $geoIntersects:
     { $geometry: { 
         type: "Point", 
         coordinates: [ 116.3426399230957, 39.95959281921387 ] 
     } } 
 } }

 ntoreturn:0 
 ntoskip:0
 nscanned:2965
 keyUpdates:0
 numYields: 2 locks(micros)
 r:136723
 nreturned:52
 reslen:23453
 103ms

The collection has about 10k records, where deliver_area is one of the fields which is a Polygon(GeoJSON) and has a 2dsphere index

This is my query:

db.area_coll.find( { 
    id: 59, 
    deliver_area: { 
        $geoIntersects: { 
            $geometry: { 
                type: "Point", 
                coordinates: [ 116.3175773620605, 39.97607231140137 ] 
            } 
        } 
    } 
})

Explain result:

{
    "cursor" : "S2Cursor",
    "isMultiKey" : true,
    "n" : 0,
    "nscannedObjects" : 0,
    "nscanned" : 3887,
    "nscannedObjectsAllPlans" : 0,
    "nscannedAllPlans" : 3887,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 5,
    "indexBounds" : {
    },
    "nscanned" : 3887,
    "matchTested" : NumberLong(666),
    "geoTested" : NumberLong(0),
    "cellsInCover" : NumberLong(1),
    "server" : "testing:27017"
}

回答1:

The query in the log does not match the query that you run as, the location is different:

[ 116.3426399230957, 39.95959281921387 ] vs.
[ 116.3175773620605, 39.97607231140137 ]

I also don't think you have reproduced your whole log line, as it just mentions area and not deliver_area.

However, they are not really slow. In the first case, it took 103ms, which in some cases might happen as your server is doing other IO. The second query took 5ms as the explain() output tells you.

But what is most striking is that your main criterion is id: 59. I don't know what your _id field is, but if you set an index on id then this should not even have to use a 2dsphere index at all — unless you have of course many documents where id=59. In that case, you could be better off with a compound key on { id: 1, deliver_area: '2dsphere' }.