MongoDB数据模式性能

时间:2012-09-02 14:36:15

标签: performance mongodb schema-design

我试图理解MongoDB文档中数组和散列的内部分配和位置(我的理解是通过数组实现的)。

在我们的域中,我们的文档中包含数千到数十万个键值对,逻辑分组最多可达5-6个深度(想想嵌套哈希值)。

我们使用点代表键中的嵌套,例如x.y.z,插入MongoDB后会自动变为:

{
    "_id" : "whatever",
    "x" : {
        "y" : {
            "z" : 5
        }
    }
}

最常见的操作是递增一个值,我们使用原子$inc,通常使用单个更新命令一次使用1000+值。随着时间的推移添加新密钥,但不是经常添加,例如100次/天。

在我看来,另一种表示方式是不在名称中使用点,而是使用其他分隔符并创建平面文档,例如

{
    "_id" : "whatever",
    "x-y-z" : 5
}

考虑到键值对的数量以及$inc更新和新密钥插入方面的使用模式,我正在寻找关于两种方法之间权衡的指导:

  • 磁盘上的空间开销

  • $inc更新的效果

  • 新密钥插页的效果

1 个答案:

答案 0 :(得分:2)

MongoDB中的文档磁盘存储采用BSON格式。这里有BSON格式的详细说明:   - http://bsonspec.org/#/specification

虽然使用短密钥名称可以节省一些磁盘(因为通过查看规范可以看到,密钥名称已嵌入到文档中),但在我看来,几乎没有任何净差异在所使用的磁盘空间方面,两个设计之间 - 使用分隔符( - )使用的额外字节通过不必为单独的键值使用字符串终止符而被买回。

对于这两种格式,$ inc更新应该几乎完全相同,因为它们都将是内存中的操作。与从磁盘读取文档所花费的时间相比,内存更新时间的任何改进都将是最小的舍入错误。

新钥匙插件的性能也应该几乎相同。如果添加新的键/值对使新文档足够小以适合磁盘上的旧位置,那么所有发生的事情都是更新内存版本并写入日记条目。最终,内存中的版本将被写入磁盘。

如果文档超出之前为其分配的空间,则新的密钥插入更成问题。在这种情况下,服务器必须将文档移动到新位置并更新指向该文档的所有索引。这通常是一个较慢的操作,应该避免。但是,您正在讨论的架构更改不应该影响文档移动的频率。再一次,我认为这是一个洗手。

我的建议是使用最适合开发人员生产力的架构。如果您遇到性能问题,那么您可以单独询问如何扩展系统或提高性能,或两者兼而有之。