2014-01-15 123 views
0

我已經到位以下蒙戈測試集羣MongoDB的慢查詢性能

  1. 沒有碎片-2
  2. 沒有配置服務器-1
  3. mongos實例-2
  4. 複製的未啓用

我有大約4100萬條記錄在整個碎片中分割,我定義了一個複合索引{field1:1,field2:1,field3:1},我的查詢是(x和y之間的字段= 1和字段2),我預計複合索引對於這些查詢很有用,但查詢響應時間大約爲8秒,對於我描述的查詢。當我執行查找時,我只指定了感興趣的字段。

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" : "[email protected]", 
    "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。感謝任何幫助。

+2

請運行'你的查詢explain'和結果添加到您的文章 –

+2

看來,查詢計劃會掃描索引LOGIN_ID每個值,共有將近180萬登錄記錄。你可以添加你的查詢和一個示例文檔。另外,您使用的是哪個版本的MongoDB? –

+0

此查詢返回多少個文檔?如果它提取的文檔太多,請嘗試'limit' –

回答

0

我看到了下面的點可能一頭扎進找到更多確切的問題:

  1. 什麼是login_time又是什麼在查詢範圍的數字到底意味着什麼?數值差異使得該範圍看起來相當寬。可能是你過濾的標準是多麼廣泛?這也是來自解釋計劃的「已掃描」的指示。

  2. 我看到索引是在login_time和login_id上,其中您的查詢在login_time和login_type上。儘管您使用的是索引,但是您的查詢條件足夠寬以涵蓋更大的索引範圍,並且由於login_type的第二條件不是索引的一部分,查詢將需要獲取所有「已掃描」文檔以確定如果它是這個查詢的有效記錄。