【发布时间】:2014-01-30 01:43:10
【问题描述】:
我有以下 mongo 测试集群
- 分片数 -2
- 没有配置服务器-1
- mongos 实例 -2
- 复制未启用
我有大约 4100 万条记录分布在各个分片中,我定义了一个复合索引 {field1:1,field2:1,field3:1},我的查询格式为 (field=1 and field2 between x and y ),我希望复合索引对这些查询有用,但是对于我描述的查询,查询响应时间约为 8 秒。我在执行 find 时只指定感兴趣的字段。
Mongos 安装在我执行查询的机器上,我正在使用 java 进行查询。
有人能解释一下可能的原因吗,为什么这个查询需要这么长时间?如果需要,我很乐意提供更多信息。
以下是解释命令的输出
{
"indexBounds": {
"LOGIN_ID": [
[
{
"$minElement": 1
},
{
"$maxElement": 1
}
]
],
"LOGIN_TIME": [
[
1262332800000,
1293782400000
]
]
},
"nYields": 7,
"millisShardTotal": 7410,
"millisShardAvg": 7410,
"numQueries": 1,
"nChunkSkips": 0,
"shards": {
"server1:27017": [
{
"nYields": 7,
"nscannedAllPlans": 1769804,
"allPlans": [
{
"cursor": "BtreeCursor LOGIN_TIME_1_LOGIN_ID_1",
"indexBounds": {
"LOGIN_ID": [
[
{
"$minElement": 1
},
{
"$maxElement": 1
}
]
],
"LOGIN_TIME": [
[
1262332800000,
1293782400000
]
]
},
"nscannedObjects": 1763903,
"nscanned": 1763903,
"n": 14081
},
{
"cursor": "BasicCursor",
"indexBounds": {},
"nscannedObjects": 5901,
"nscanned": 5901,
"n": 0
}
],
"millis": 7410,
"nChunkSkips": 0,
"server": "server2:27017",
"n": 14081,
"cursor": "BtreeCursor LOGIN_TIME_1_LOGIN_ID_1",
"oldPlan": {
"cursor": "BtreeCursor LOGIN_TIME_1_LOGIN_ID_1",
"indexBounds": {
"LOGIN_ID": [
[
{
"$minElement": 1
},
{
"$maxElement": 1
}
]
],
"LOGIN_TIME": [
[
1262332800000,
1293782400000
]
]
}
},
"scanAndOrder": false,
"indexBounds": {
"LOGIN_ID": [
[
{
"$minElement": 1
},
{
"$maxElement": 1
}
]
],
"LOGIN_TIME": [
[
1262332800000,
1293782400000
]
]
},
"nscannedObjectsAllPlans": 1769804,
"isMultiKey": false,
"indexOnly": false,
"nscanned": 1763903,
"nscannedObjects": 1763903
}
]
},
"n": 14081,
"cursor": "BtreeCursor LOGIN_TIME_1_LOGIN_ID_1",
"oldPlan": {
"cursor": "BtreeCursor LOGIN_TIME_1_LOGIN_ID_1",
"indexBounds": {
"LOGIN_ID": [
[
{
"$minElement": 1
},
{
"$maxElement": 1
}
]
],
"LOGIN_TIME": [
[
1262332800000,
1293782400000
]
]
}
},
"numShards": 1,
"clusteredType": "ParallelSort",
"nscannedAllPlans": 1769804,
"nscannedObjectsAllPlans": 1769804,
"millis": 7438,
"nscanned": 1763903,
"nscannedObjects": 1763903
}
我的数据库中的示例文档如下
{
"_id" : ObjectId("52d5192c1a45f84e48c24e2f"),
"LOGIN_ID" : <loginId>,
"LOGIN_TIME" : NumberLong("1372343932000"),
"BUSINESS_ID" : <businessId>,
"USER_ID" : <userid>,
"EMAIL" : "a@b.com",
"SITE_POD_NAME" : "x",
"USER_AGENT" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML. like Gecko) Chrome/26.0.1410.43 Safari/537.31"
}
上面的文档中还有一些其他字段我不能暴露在外面,但它是字符串和字符串的简单键值
这就是我查询数据库的方式
DBObject dbObject = new BasicDBObject("BUSINESS_ID", businessId)
.append("LOGIN_TIME",
new BasicDBObject("$gte",start).append("$lt", end))
.append("LOGIN_TYPE", loginType);
long startTime = System.currentTimeMillis();
DBObject keys = new BasicDBObject("LOGIN_TIME", 1);
DBCursor find = collection.find(dbObject, keys);
int count = 0;
while (find.hasNext()) {
find.next();
count++;
}
long endTime = System.currentTimeMillis();
Mongo DB 版本是 2.4.9。感谢任何帮助。
【问题讨论】:
-
请运行
explain的查询,并将结果添加到您的帖子中 -
查询计划似乎扫描了索引中LOGIN_ID的每一个值,总共差不多180万条登录记录。您能否添加您的查询和示例文档。另外,您使用的是哪个版本的 MongoDB?
-
这个查询返回多少个文档?如果它获取的文档太多,请尝试
limit -
您好,这个查询返回大约14000个文档,但我只是指定要返回的LOGIN_TIME,所以返回的文档大小应该不会太大
标签: mongodb