[英]mongodb slow query performance
我有以下mongo測試集群
我有大約4100萬條記錄分布在各個分片上,我定義了一個復合索引{field1:1,field2:1,field3:1},我的查詢形式為(field = 1和field2在x和y之間),我期望復合索引對這些查詢有用,但是我描述的查詢的查詢響應時間約為8秒。 執行查找時,我僅指定感興趣的字段。
Mongos安裝在執行查詢的機器上,並且我正在使用Java進行查詢。
有人可以解釋一下這種查詢為什么花這么長時間的可能原因嗎? 如果需要,我很樂意提供更多信息。
以下是explain命令的輸出
{
"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"
}
上面的文檔中還有其他一些字段,我無法在外面公開,但是它是string和string的簡單鍵值
這就是我查詢數據庫的方式
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。 感謝任何幫助。
我發現以下幾個方面可能會發現更多有關確切問題的信息:
什么是login_time?查詢范圍內的數字實際上是什么意思? 通過數字差異,該范圍看起來相當寬。 可能您的過濾條件范圍很廣嗎? 從解釋計划的“ nscanned”也可以看出這一點。
我看到索引在login_time和login_id上,而您的查詢在login_time和login_type上。 只需說明一下,盡管您正在使用索引,但是您的查詢條件足夠寬,可以覆蓋更大的索引范圍,並且由於login_type的第二個條件不屬於索引,因此查詢將需要獲取所有“ nscanned”文檔來確定如果它是此查詢的有效記錄。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.