我们目前正在研究MongoDB,以作为高度分散的科学数据数据库的可能解决方案。根据我们的查询要求,我们选择了一个包含文档的单个集合,每个文档代表一个对象及其属性,数量约为450。典型的文档结构如下:
d = {'patch': '12345-1,1',
'X': { (120 key-value pairs) },
'A': { (64 key-value pairs) },
...
(4 more such embedded documents)
}
在X内,有一个整数标志。该标志是一个32位整数,每个位代表一个布尔标志。当布尔标志的数量很大时,这是一种存储布尔标志的常用方法。有一个查找表,显示哪个位置对应于哪个Boolean属性。第15位与我们的特定查询集相关。文件总数为600,000,分布在3个台式机(8GB RAM和i7 CPU,标准5400 RPM旋转硬盘驱动器)上。
要编写的查询很简单-我们需要对所有文档的计数,这些文档的特定标志整数的第15位设置为1。
db.coll.find(
{'X.flag1': {$bitsAllSet: [14]}}
).count()
此查询平均花费的时间为19783毫秒。这对我们来说不是可接受的时间。我们尝试使用聚合而不是基于标准find()的查询来改进此问题。
db.coll.aggregate([
'$match': {
'X.flag1': {$bitsAllSet: [14]}
},
'$group': {
_id: 0,
count: {$sum: 1}
}
])
这大约需要10,000毫秒。尽管这是一个改进(我认为是由于Aggregation框架的高效C ++实现),但它仍然超出了我们想要的性能。下一步是实际上隔离隐藏在第15位的标志,并将其设置为文档中的单独密钥。这将导致与上面相同的查询,但是我们将使用$bitsAllSet: [14]
而不是使用X.is_primary: 1
。对于find()和aggregate(),各自的时间分别为19,000 ms和8,500 ms。没有什么改善。
所以,我希望人们可以帮助的两个问题是:
编辑:按照建议,我正在共享.explain()的输出。输出用于未索引is_primary
的集合。但是,正如注释部分所述,对于布尔值,索引的存在不应影响基于布尔标志的查询的性能。