java - 批量插入大型 MongoDB 集合的性能缓慢
问题描述
我有 JSON 格式的数据,其中包含要插入 MongoDB 数据库的数百万条记录。我创建了一个 JAVA 程序,它读取 JSON 文件,对其进行解析并使用该方法将其批量插入到 MongoDB 集合中insertMany()
。每个批量插入包含 10000 个文档。文档的平均大小为 13 kB。在向集合中插入大约 300 000 个文档后,插入的性能逐渐开始变慢。除了 MongoDB 提供的默认索引之外,集合上没有索引。
我查看了 mongod.log 以诊断问题,看起来在集合包含大约 300 000 个文档之后,每个后续的批量插入都会在整个集合上导致一个带有 COLLSCAN 的聚合命令。在集合包含 3 000 000 个文档后,COLLSCAN 花费了大约 30 秒。批量插入操作本身的时间没有变化,平均停留在 200 毫秒/10000 个文档。
可以在此处找到来自 MongoDB 的完整日志文件:https ://pastebin.com/STDZTJJU
以下 JSON 输出是在从 mongod.log 文件中提取的每个插入之后执行的聚合命令的示例。此处 COLLSCAN 耗时超过 6 秒。
我可以做些什么来避免每次批量插入后的集合扫描?
I COMMAND [conn2] command diploma.patent command: aggregate {
aggregate: "patent",
pipeline: [
{ $match: {}
},
{ $group: {
_id: null,
n: { $sum: 1
}
}
}
], cursor: {},
$db: "diploma",
$readPreference: { mode: "primaryPreferred" }
}
planSummary: COLLSCAN
keysExamined: 0
docsExamined: 2453599
cursorExhausted: 1
numYields: 19422
nreturned: 1
reslen: 123
locks: {
Global: {
acquireCount: {
r: 19424
}
},
Database: {
acquireCount: {
r: 19424
}
},
Collection: {
acquireCount: {
r: 19424
}
}
} protocol:op_msg 6274ms
解决方案
推荐阅读
- database - EAV 建模数据库模式来存储设置,这是正确的方法吗?
- php - 如何在php中将数组的索引值设置为0?
- python - 如何清理字符串以使其仅包含可打印的 ASCII 字符?
- html - 如何添加不透明度的背景图像+背景颜色?
- azure - 使用 Kudu API 将带有 serviceBusTrigger 的 azure 函数部署到现有函数应用程序,即使在手动同步触发器后也不会触发
- javascript - 滚动时的 jQuery 导航栏过渡。如何调整特定的过渡点
- php - 产品和品牌页面上的分页按钮在 Prestashop 1.7.5.1 中不起作用
- docker - 我可以将本地构建部署到虚拟机中的 docker swarm 吗?
- django - 在 Django 模型和序列化程序中指定 AM 和 PM 时间字段
- java - 如何在相互交织的数据库中添加两个详细信息