MongoDB比单个查询慢了许多或几个数量级

时间:2013-11-19 15:39:14

标签: performance mongodb logical-operators

当查询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

0 个答案:

没有答案