約 500km² のポリゴンで geoWithin クエリを実行していますが、実行に非常に時間がかかり、30 秒から 5 分ほどかかります。コレクションはわずか 18 万行で、ポリゴンは 2km² から 10,000km² の範囲である可能性があります。サーバーには約4GBのRAMがあります。(ネットワークの遅延をなくすために) ローカルで実行しても、顕著な効果はありません。
コレクションに 2dsphere インデックスを設定し、フィールドの数を _id のみを返すように制限しました (今のところ)。
これは私のドキュメントがどのように見えるかです:
{
"_id" : ObjectId("..."),
"geometry" : {
"type" : "MultiPolygon",
"coordinates" : [[...]]
},
"area_sq_m" : 6699.1309787227955894
}
これが私のインデックスです:
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "db.output_areas"
},
{
"v" : 1,
"key" : {
"geometry" : "2dsphere"
},
"name" : "geometry_2dsphere",
"ns" : "db.output_areas",
"2dsphereIndexVersion" : 2
}
]
これが私のクエリです:
{
"geometry": {
$geoWithin: {
$geometry: {
type: 'Polygon',
coordinates: [[ [lng,lat], [lng,lat], [lng,lat] ...]]
}
}
}
}
そして、これが実行からの出力ですexplain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db.output_areas",
"indexFilterSet" : false,
"parsedQuery" : {
"geometry" : {
"$geoWithin" : {
"$geometry" : {
"type" : "Polygon",
"coordinates" : [...]
}
}
}
},
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"_id" : 1
},
"inputStage" : {
"stage" : "KEEP_MUTATIONS",
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"geometry" : {
"$geoWithin" : {
"$geometry" : {
"type" : "Polygon",
"coordinates" : [...]
}
}
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"geometry" : "2dsphere"
},
"indexName" : "geometry_2dsphere",
"isMultiKey" : true,
"direction" : "forward",
"indexBounds" : {
"geometry" : [
"[\"2f0332301\", \"2f0332301\"]",
"[\"2f03323011\", \"2f03323011\"]",
"[\"2f033230111\", \"2f033230112\")",
"[\"2f033230112\", \"2f033230112\"]",
"[\"2f0332301120\", \"2f0332301121\")",
"[\"2f0332301121\", \"2f0332301121\"]",
"[\"2f03323011210\", \"2f03323011211\")",
"[\"2f03323011211\", \"2f03323011212\")",
"[\"2f1003230\", \"2f1003230\"]",
"[\"2f10032300\", \"2f10032300\"]",
"[\"2f100323000\", \"2f100323001\")"
]
}
}
}
}
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"version" : "3.0.4"
},
"ok" : 1
}
これは、インデックスが使用されていることを示唆しています。小さい領域で試してみると、クエリは高速になり、領域が大きくなると遅くなります。
ここに私のコレクション統計があります:
{
"ns" : "db.output_areas",
"count" : 181408,
"size" : 3062445568,
"avgObjSize" : 16881,
"numExtents" : 22,
"storageSize" : 3927183360,
"lastExtentSize" : 1021497344,
"paddingFactor" : 1,
"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.",
"userFlags" : 1,
"capped" : false,
"nindexes" : 2,
"totalIndexSize" : 35606480,
"indexSizes" : {
"_id_" : 5894896,
"geometry_2dsphere" : 29711584
},
"ok" : 1
}
コマンドを実行db.setProfilingLevel(2)
し、クエリを再実行してから、db.system.profile
コレクションを調べました。
最初のレコードは実際のクエリです ( "op": "query"
)
"op": "getmore"
次に、残りのデータをフェッチしていると思われる( ) を使用したさらに 7 つのクエリ。
各クエリは 1000 行 ( "nreturned": 1000
) を生成し、各クエリの平均は 4000millis
です。
geojson クエリが 2 秒を超えて 100 万行を超えることについて人々が不平を言っている多くの質問を読んだので、明らかに単純なものが欠けています。