首页 > 解决方案 > 批量插入大型 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

标签: javamongodbperformanceinsert

解决方案


推荐阅读