mongodb查询性能慢

时间:2014-01-15 06:14:30

标签: mongodb

我有以下mongo测试集群

  1. 没有分片-2
  2. 否配置服务器-1
  3. mongos instances -2
  4. 未启用复制
  5. 我在分片中分割了大约4100万条记录,我已经定义了一个复合索引{field1:1,field2:1,field3:1},我的查询格式为(field = 1,x和y之间为field2) ),我希望复合索引对这些查询有用,但是我所描述的查询的查询响应时间大约是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"
        }
    

    上面的doc中还有一些我无法在外面公开的字段,但它是字符串和字符串的简单键值

    这就是我查询db

    的方法
        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。感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

我看到以下几点可以找到更多关于确切问题的信息:

  1. 什么是login_time,查询范围内的数字实际上是什么意思?数值差异范围看起来很宽。可能是你的过滤标准是广泛的吗?这也是解释计划中“nscanned”的指示。

  2. 我看到索引在login_time和login_id上,您的查询在login_time和login_type上。虽然您正在使用索引,但您的查询条件足够宽以覆盖更大的索引范围,并且由于login_type的第二个条件不是索引的一部分,因此查询需要获取所有“nscanned”文档以确定如果它是此查询的有效记录。