我正在使用mongoDB存储一个querylog并获取一些关于它的统计信息。 我存储在mongoDB中的对象包含查询的文本,日期, 用户,如果用户点击某些结果等等。
现在我正在尝试检索用户在某一天未点击的所有查询 用java。我的代码大概是这样的:
DBObject query = new BasicDBObject();
BasicDBObject keys = new BasicDBObject();
keys.put("Query", 1);
query.put("Date", new BasicDBObject("$gte", beginning.getTime()).append("$lte", end.getTime()));
query.put("IsClick", false);
...
DBCursor cur = mongoCollection.find(query, keys).batchSize(5000);
查询的输出包含我需要迭代的大约20k条记录。 问题是需要几分钟:(。我认为不正常。 从服务器日志中我看到:
Wed Nov 16 16:28:40 query db.QueryLogRecordImpl ntoreturn:5000 reslen:252403 nscanned:59260 { Date: { $gte: 1283292000000, $lte: 1283378399999 }, IsClick: false } nreturned:5000 2055ms
Wed Nov 16 16:28:40 getmore db.QueryLogRecordImpl cid:4312057226672898459 ntoreturn:5000 query: { Date: { $gte: 1283292000000, $lte: 1283378399999 }, IsClick: false } bytes:232421 nreturned:5000 170ms
Wed Nov 16 16:30:27 getmore db.QueryLogRecordImpl cid:4312057226672898459 ntoreturn:5000 query: { Date: { $gte: 1283292000000, $lte: 1283378399999 }, IsClick: false } bytes:128015 nreturned:2661 --> 106059ms
因此,检索第一个块需要2秒,第二个0.1秒,第三个106秒!奇怪的.. 我尝试更改批量大小,在Date和IsClick上创建索引,重启机器:P但没办法。哪里我错了?
答案 0 :(得分:5)
这里有几个因素会影响速度。有必要收集一些额外的数据来确定原因。
一些潜在的问题:
IsClick/Date
上建立索引。这使得范围第二是正常的建议。请注意,这与Date/IsClick
上的索引不同,顺序很重要。在查询中尝试.explain()
以查看正在使用的索引。reslen
)和12k文件,所以这可能不是问题。iostat
或resmon
(Windows)等工具来识别“转到磁盘”,以监控磁盘活动。根据个人经验,我强烈怀疑#3,可能会因为#1而恶化。我会在运行.explain()
查询时开始观察IO。这应该会迅速缩小可能出现问题的范围。