java - MongoDB Java API 读取速度慢
问题描述
我们正在从本地 MongoDB 读取集合中的所有文档,性能不是很出色。
我们需要转储所有数据,不要担心为什么,只要相信它确实需要并且没有解决办法。
我们有 4mio 文档,看起来像:
{
"_id":"4d094f58c96767d7a0099d49",
"exchange":"NASDAQ",
"stock_symbol":"AACC",
"date":"2008-03-07",
"open":8.4,
"high":8.75,
"low":8.08,
"close":8.55,
"volume":275800,
"adj close":8.55
}
我们现在使用这个简单的代码来阅读:
MongoClient mongoClient = MongoClients.create();
MongoDatabase database = mongoClient.getDatabase("localhost");
MongoCollection<Document> collection = database.getCollection("test");
MutableInt count = new MutableInt();
long start = System.currentTimeMillis();
collection.find().forEach((Block<Document>) document -> count.increment() /* actually something more complicated */ );
long start = System.currentTimeMillis();
我们以 16 秒(250k 行/秒)的速度读取整个集合,这对于小文档来说真的一点也不令人印象深刻。请记住,我们要加载 800mio 行。没有聚合、map reduce 或类似的可能。
这是否与 MongoDB 一样快,或者是否有其他方法可以更快地加载文档(其他技术、移动 Linux、更多 RAM、设置……)?
解决方案
您没有指定您的用例,因此很难告诉您如何调整查询。(即:谁愿意一次加载 8 亿行只是为了计数?)。
鉴于您的架构,我认为您的数据几乎是只读的,并且您的任务与数据聚合有关。
您当前的工作只是读取数据,(很可能您的驱动程序将批量读取),然后停止,然后执行一些计算(地狱是的,一个 int 包装器用于更多地增加处理时间),然后重复。这不是一个好方法。如果您不以正确的方式访问数据库,它就不会神奇地快速。
如果计算不是太复杂,我建议你使用聚合框架而不是全部加载到你的 RAM 中。
您应该考虑改善聚合的一些事情:
- 将您的数据集划分为较小的集合。(例如:分区
date
,分区exchange
...)。添加索引以支持该分区并在分区上操作聚合然后组合结果(典型的分治法) - 项目仅需要的字段
- 过滤掉不必要的文件(如果可能的话)
- 如果您无法在内存上执行聚合(如果您达到每个管道 100MB 的限制),请允许使用磁盘。
- 使用内置管道来加速你的计算(例如:
$count
你的例子)
如果您的计算太复杂而无法使用聚合框架来表达,请使用mapReduce
. 它在mongod
进程上运行,数据不需要通过网络传输到您的内存中。
更新
所以看起来你想做一个 OLAP 处理,而你停留在 ETL 步骤。
您不需要也必须避免每次都将整个 OLTP 数据加载到 OLAP。只需要将新的更改加载到您的数据仓库。然后首先数据加载/转储需要更多时间是正常且可以接受的。
首次加载时,应考虑以下几点:
- 分而治之,再次将您的数据分解为较小的数据集(使用日期/交换/股票标签等谓词......)
- 进行并行计算,然后组合你的结果(你必须正确地划分你的数据集)
- 批量计算而不是处理
forEach
:加载数据分区然后计算而不是逐个计算。
推荐阅读
- listview - 搜索栏获取文本但不过滤列表
- google-apps-script - Google Apps Script Utilities.base64Decode 异常:无法解码字符串
- neo4j - Neo4j 错误 | 列表
| 错误-org.neo4j.ogm.exception.core.InvalidPropertyFieldException - node.js - 如何用 express 解析 JWT?
- mysql - 如何在同一个表中使用 SELECT WEEK() 更新,多于 1 行 [mysql]
- c - 为什么循环有问题(pset2 替换)
- python - 类“property”没有定义“__getitem__”,因此不能在其实例上使用“[]”运算符
- c++ - constexpr constexpr 函数指针数组
- php - 我试图通过 PHP 创建一个表(“cats”)但无法访问数据库
- android - 在cardview中使用意图时没有响应