首页 > 解决方案 > MongoDB - 简单查询的性能瓶颈

问题描述

我们目前正在研究 MongoDB 作为用于科学数据的高度分布式数据库的可能解决方案。鉴于我们的查询要求,我们选择了由文档组成的单个集合,每个文档代表一个对象及其属性,数量约为 450。典型的文档结构如下:

d = {'patch': '12345-1,1',
     'X': { (120 key-value pairs) },
     'A': { (64 key-value pairs) },
     ...
     (4 more such embedded documents)
    }

在 X 中,有一个整数标志。该标志是一个 32 位整数,每个位代表一个布尔标志。当布尔标志的数量相当大时,这是存储布尔标志的常用方法。有一个查找表显示哪个位置对应于哪个布尔属性。第 15 位与我们的特定查询集相关。文档总数为 600,000,分片在 3 个桌面(8GB RAM 和 i7 CPU,标准 5400 RPM 旋转硬盘驱动器)。

正在编写的查询很简单——我们想要一个特定标志整数的第 15 位设置为 1 的所有文档的计数。

db.coll.find(
    {'X.flag1': {$bitsAllSet: [14]}}
).count()

此查询所用的平均时间为 19,783 毫秒。这不是我们可以接受的时间。我们尝试使用聚合而不是基于标准 find() 的查询来改进这一点。

db.coll.aggregate([
    '$match': {
        'X.flag1': {$bitsAllSet: [14]}
    },
    '$group': {
        _id: 0,
        count: {$sum: 1}
    }
])

这大约需要 10,000 毫秒。虽然这是一个改进(我认为这是因为聚合框架的高效 C++ 实现),但它仍然超出了我们想要的性能。下一步是实际隔离隐藏在第 15 位中的标志,并使其成为文档中的单独键。这将导致与上述相同的查询,但$bitsAllSet: [14]我们将使用X.is_primary: 1. 对于 find() 和 aggregate(),各自的时间分别为 19,000 毫秒和 8,500 毫秒。几乎没有什么改善。

所以,我希望人们可以帮助解决的两个问题是:

编辑:正如建议的那样,我正在共享 .explain() 的输出。输出用于is_primary未编制索引的集合。但正如评论部分所讨论的,对于布尔值,索引的存在不应影响基于布尔标志的查询的性能。

Pastebin 链接(2 周到期)

标签: databasemongodbperformanceanalytics

解决方案


推荐阅读