私は一種の逆範囲検索のようなものである次のクエリを持っている:だけ$のLTEの識別子を使用して実行すると
db.ip_ranges.find({ $and: [{ start_ip_num: { $lte: 1204135028 } }, { end_ip_num: { $gt: 1204135028 } }] })
、クエリはすぐに返されます。しかし、同じクエリで$ gtと$ lteの両方を実行すると、非常に遅い(秒単位)。
start_ip_numフィールドとend_ip_numフィールドの両方にインデックスが付けられます。
このクエリを最適化するにはどうすればよいですか?
EDIT
私は、クエリの説明()関数を使用する場合、私は以下のようになります。私は、複合インデックスを追加したら
{
"cursor" : "BtreeCursor start_ip_num_1",
"nscanned" : 452336,
"nscannedObjects" : 452336,
"n" : 1,
"millis" : 2218,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"start_ip_num" : [
[
-1.7976931348623157e+308,
1204135028
]
]
}
}
EDIT 2
を、 explain()関数は、以下を返します。
{
"cursor" : "BtreeCursor start_ip_num_1_end_ip_num_1",
"nscanned" : 431776,
"nscannedObjects" : 1,
"n" : 1,
"millis" : 3433,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"start_ip_num" : [
[
-1.7976931348623157e+308,
1204135028
]
],
"end_ip_num" : [
[
1204135028,
1.7976931348623157e+308
]
]
}
}
ただし、perfはまだ不十分です(秒単位)。
'.find({...})。explain()' 'は良い出発点です。 Wes Freemanが尋ねるように、 '' {start_ip_nm:1、end_ip_num:1} ''のインデックスはありますか? – slee
あなたが解決しなければならないことは、 '$と'を使う代わりに単一のクエリセレクタオブジェクトを使うことです。 'db.ip_ranges.find({start_ip_num:{$ lte:1204135028}、end_ip_num:{$ gt:1204135028}})' – JohnnyHK
Bツリーは1つの一致を見つけるために> 400kのエントリをスキャンする必要があります。それが役立つかどうかを確認するためにボックスクエリを試してみてください。私はあなたが1秒未満でそれを得るだろうと確信しています。 –