MongoDB 索引化

3

我们有一个包含近4000万条记录的MongoDB集合。当前集合的大小为5GB。该集合中存储的数据包含以下字段:

_id: "MongoDB id"
userid: "user id" (int)
mobile: "users mobile number" (int)
transaction: "transaction id" (int)
sms: "message sent to user mobile" (text)
created_dt: "unix timestamp of the transaction"

除了默认创建的_id索引外,我们还在mobile和transaction字段上定义了单独的索引。

然而,以下查询需要花费60至120秒左右才能完成:

{
    mobile:<users mobile number>
}

我使用RockMongo来访问MongoDB。MongoDB托管在一台拥有16GB内存的服务器上。这台服务器上几乎有8GB的可用内存。

我在这里做错了什么?

更新:

explain的输出:

{
    "cursor" : "BasicCursor",
    "nscanned" : 37145516,
    "nscannedObjects" : 37145516,
    "n" : 37145516,
    "millis" : 296040,
    "nYields" : 1343,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {
    }
}

在查询时的 mongostat 输出

insert  query update delete getmore command flushes mapped  vsize    res faults locked % idx miss %     qr|qw   ar|aw  netIn netOut  conn       time 
    13      2      0      0       0       1       0   168g   336g  6.86g      1        1          0       0|0     1|0    21k     1k    19   11:30:04 
    16      0      0      0       0       1       0   168g   336g  6.88g      0      0.1          0       0|0     1|0    21k     1k    19   11:30:05 
    14      0      0      0       0       1       0   168g   336g  6.86g      0        0          0       0|0     1|0    29k     1k    19   11:30:06 
    10      0      0      0       0       1       0   168g   336g  6.86g      0        0          0       0|0     1|0    19k     1k    19   11:30:07 
    16      0      0      0       0       1       0   168g   336g  6.88g      0      0.1          0       0|0     1|0    21k     1k    19   11:30:08 
     9      0      0      0       0       1       0   168g   336g  6.89g      0        0          0       0|0     1|0    13k     1k    19   11:30:09 
    19      0      0      0       0       1       0   168g   336g  6.89g      0        0          0       0|0     1|0    27k     1k    19   11:30:10 
    12      0      0      0       0       1       0   168g   336g  6.89g      1      1.2          0       0|0     1|0    24k     1k    19   11:30:11 
    17      0      0      0       0       1       0   168g   336g  6.89g      1      1.7          0       0|0     1|0    31k     1k    19   11:30:12 
    15      0      0      0       0       1       0   168g   336g  6.89g      0        0          0       0|0     1|0    19k     1k    19   11:30:13 

更新2:

最近,我们曾在同一台MongoDB服务器上存储了另一个包含大约13亿个文档的集合。现在已经将该集合删除(drop)。这可能解释了mongostat输出中的mapped / vsize列。

该服务器还存储有6个其他集合,其中有频繁插入操作。目前总的存储大小约为35GB。

更新3:

定义在集合上的索引。使用RockMongo创建。

[
{
    "v" : 1,
    "key" : {
        "_id" : 1
    },
    "ns" : "mymongodb.transaction_sms_details",
    "name" : "_id_"
},
{
    "v" : 1,
    "key" : {
        "_transaction_mobile_" : 1
    },
    "ns" : "mymongodb.transaction_sms_details",
    "background" : 1,
    "name" : "mobile"
},
{
    "v" : 1,
    "key" : {
        "_transaction_transaction_" : 1
    },
    "ns" : "mymongodb.transaction_sms_details",
    "background" : 1,
    "name" : "transaction"
}
]

你是否对移动字段进行了索引?http://www.mongodb.org/display/DOCS/Indexes - sics
问题中提到他们为_id、mobile和transaction创建了三个索引。 - Thilo
每个手机号码返回多少份文件? - Thilo
是的。我们已经索引了3个字段:1. _id字段(默认创建);2. 手机号码字段;3. 交易字段。 - Nikhil
文档数量可能会有所变化。平均值约为60个。任何手机号码的条目数不能超过160个。 - Nikhil
显示剩余4条评论
1个回答

2
RockMongo生成的密钥明显不正确。
    "_transaction_mobile_" : 1
    "_transaction_transtion_" : 1

我不知道RockMongo出了什么问题,但我认为以下方法可以解决此问题:

db.xxx.dropIndexes();
db.xxx.ensureIndex({mobile: 1});
db.xxx.ensureIndex({transaction: 1});

注意:这可能需要非常长的时间。不要在正在运行的生产机器上进行此操作。


感谢您。RockMongo允许用户编辑索引名称以及要建立索引的字段名称。我认为某个创建索引的人更新了字段名称而不是索引名称。RockMongo没有检查确保要建立索引的字段实际上存在于集合中。 - Nikhil
你应该在后台操作模式下进行重建索引。 - Aurélien B
可能不应该进行检查,因为您可以为未来的字段添加索引。也许只是一个警告... :) 至少你得到了解决方案! - Eve Freeman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接