database - 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 毫秒。几乎没有什么改善。
所以,我希望人们可以帮助解决的两个问题是:
- 这是我可以从 MongoDB 社区版获得的最终性能吗?我知道有一个带有内存引擎的企业版。但我的问题更具体到社区版。有什么技巧可以用来加快查询速度吗?
- 我慢慢地发现,至少对于我们需要的复杂服务器端分析和查询,MongoDB 在我们编写的查询的复杂性和性能瓶颈方面都被证明是难以使用的。关于我可能考虑的其他数据库的任何建议。
编辑:正如建议的那样,我正在共享 .explain() 的输出。输出用于is_primary
未编制索引的集合。但正如评论部分所讨论的,对于布尔值,索引的存在不应影响基于布尔标志的查询的性能。
解决方案
推荐阅读
- perl - 使用 sed/awk/perl 获取列列表
- docker - 在 docker 上运行的 Gitlab 社区 - Heathcheck
- python - 如何在 python-socketio 上发送消息
- android-studio - 如何确定 Android Studio 中方法调用(或特定行)代码的数量?
- c# - 如何从 xml 文件中读取多个属性
- java - 我们如何编辑 Java 内置类,例如 Java.util.Scanner?
- java - ActionListener 按钮什么都不做
- javascript - 使用 AJAX 和按钮提交的 Flask 上传文件不起作用
- css - 用线悬停挥动
- flutter - 如何在 Flutter Tabs 中添加圆点作为指示器?