I've a database with over 3 million documents.
When running a find() on a GeoJSON Point field with a 2DSphere index the query is very slow (12,000 ms), while running the same find() using a 2D index is very fast (under 1 ms).
Steps to reproduce:
1. Create a collection named "objects" with more than 1 million documents.
2. Use the following simple schema:
{
"id": 1,
"location": {
"type": "Point",
"coordinates": [-118.491356, 34.02444]
}
}
3. Create a 2DSphere index in the location field:
objects.ensureIndex(
);
4. Create a 2D index in the location.coordinates field:objects.ensureIndex(
{"location.coordinates": "2d"});
5. Run this 2DSphere search query on the mongo client:
db.objects.find({
"location": {
"$near": {
"$maxDistance": 10000,
"$geometry": {
"type": "Point",
"coordinates": [-118.491356, 34.02444]
}
}
}
}).limit(1000).explain();
You'll notice a high number of scanned objects and a very high response
time, even though the S2NearCursor is being used. Here's the output I get from explain:
... }).limit(1000).explain();
{
"cursor" : "S2NearCursor",
"isMultiKey" : true,
"n" : 1000,
"nscannedObjects" : 1000,
"nscanned" : 1842767,
"nscannedObjectsAllPlans" : 1000,
"nscannedAllPlans" : 1842767,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 7,
"nChunkSkips" : 0,
"millis" : 12565,
"indexBounds" : {
},
"nscanned" : 1842767,
"matchTested" : NumberLong(1695623),
"geoMatchTested" : NumberLong(1695623),
"numShells" : NumberLong(1),
"keyGeoSkip" : NumberLong(147144),
"returnSkip" : NumberLong(3577),
"btreeDups" : NumberLong(0),
"inAnnulusTested" : NumberLong(1695623),
"server" : "mongoserver:27017"
}
6. Run this 2D search query on the mongo client:
db.objects.find({
"location.coordinates": {
"$near": [-118.491356, 34.02444],
"$maxDistance": 10000
}
}).limit(1000).explain();
Now you'll get a very fast response time. Here's the output I get from explain:
{
"cursor" : "GeoSearchCursor",
"isMultiKey" : false,
"n" : 1000,
"nscannedObjects" : 1000,
"nscanned" : 1000,
"nscannedObjectsAllPlans" : 1000,
"nscannedAllPlans" : 1000,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
},
"server" : "mongoserver:27017"
}
7. You can use geoNear instead of near when searching on the 2DSphere-indexed field and you'll get the same huge response time.
- duplicates
-
SERVER-19039 geoNear scans the same index cells multiple times, slowing down queries with many search intervals
-
- Closed
-