当查询10K对象时,看起来使用find_one单独查询每个对象比查询$or
要快得多,这没有多大意义。下面的东西是否有问题?对于前200个左右的对象,查询似乎会暂停一段时间,然后很快找到所有其他对象。
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
public class MongoOrVsSingleQuery {
public static void main(String[] args) throws Exception {
MongoClient mc = new MongoClient();
mc.getDB("foo").dropDatabase();
DBCollection foo = mc.getDB("foo").getCollection("foo");
DBObject index = new BasicDBObject("a", 1);
index.put("b", 1);
foo.ensureIndex(index);
List<DBObject> lo = new LinkedList<DBObject>();
for (int i = 1; i < 10001; i++) {
DBObject o = new BasicDBObject("a", i);
o.put("b", 1);
lo.add(o);
}
System.out.println("insert: " + new Date());
foo.insert(lo);
for (DBObject o: lo) {
o.removeField("_id");
}
DBObject query = new BasicDBObject("$or", lo);
System.out.println("find one: " + new Date());
for (DBObject o: lo) {
foo.findOne(o).get("a");
}
System.out.println("find: " + new Date());
DBCursor dbc = foo.find(query);
for (DBObject o: dbc) {
if ((int) o.get("a") % 100 == 0) {
System.out.println("find obj: " + o.get("a") + " " + new Date());
}
}
System.out.println("done: " + new Date());
}
}
输出:
insert: Tue Nov 19 07:16:02 PST 2013
find one: Tue Nov 19 07:16:02 PST 2013
find: Tue Nov 19 07:16:05 PST 2013
find obj: 100 Tue Nov 19 07:16:08 PST 2013
find obj: 200 Tue Nov 19 07:21:22 PST 2013
find obj: 300 Tue Nov 19 07:21:22 PST 2013
*snip*
find obj: 9900 Tue Nov 19 07:21:22 PST 2013
find obj: 10000 Tue Nov 19 07:21:22 PST 2013
done: Tue Nov 19 07:21:22 PST 2013
在查询期间,这是currentOp()的典型输出:
~$ mongo
MongoDB shell version: 2.4.3
connecting to: test
> use foo
> db.currentOp()
{
"inprog" : [
{
"opid" : 40221,
"active" : true,
"secs_running" : 241,
"op" : "getmore",
"ns" : "foo.foo",
"query" : {
"$msg" : "query not recording (too large)"
},
"client" : "127.0.0.1:58696",
"desc" : "conn7",
"threadId" : "0x7fef961f8700",
"connectionId" : 7,
"locks" : {
"^" : "r",
"^foo" : "R"
},
"waitingForLock" : false,
"numYields" : 124,
"lockStats" : {
"timeLockedMicros" : {
"r" : NumberLong(390668733),
"w" : NumberLong(0)
},
"timeAcquiringMicros" : {
"r" : NumberLong(195362976),
"w" : NumberLong(0)
}
}
}
]
}
> db.version()
2.4.3