MongoDB java驱动程序批量更新与常规更新性能

MongoDB java驱动程序批量更新与常规更新性能,java,performance,mongodb,mongodb-query,mongodb-java,Java,Performance,Mongodb,Mongodb Query,Mongodb Java,我在应用程序中使用MongoDB java驱动程序 在一个特定的用例中,我必须更新集合中的大量记录。我发现使用MongoDb Java驱动程序的BulkUpdateAPI与常规更新相比性能差得多。这真的很奇怪,我以为批量更新方法应该提高性能 以下是具体细节- 集合有270k条记录。大约有17k个update语句要执行。数据库是本地安装的 批量更新代码 公共无效置乱(String collectionName、String fieldName){ 最终列表distinctValues=getDis

我在应用程序中使用MongoDB java驱动程序

在一个特定的用例中,我必须更新集合中的大量记录。我发现使用MongoDb Java驱动程序的
BulkUpdate
API与常规更新相比性能差得多。这真的很奇怪,我以为批量更新方法应该提高性能

以下是具体细节- 集合有
270k条记录
。大约有
17k个update
语句要执行。数据库是本地安装的

批量更新代码

公共无效置乱(String collectionName、String fieldName){
最终列表distinctValues=getDistinctValues(collectionName,fieldName);
final BulkWriteOperation bulk=mongoDb.getCollection(collectionName).InitializeUnderedBulkOperation();
for(最终字符串实际值:distinctValues){
如果(!StringUtils.isEmpty(实际值)){
最终字符串扰码值=Get扰码值(实际值);
更新(字段名、实际值、加扰值、批量);
}
}
bulk.execute();
}
受保护的无效更新(字符串字段名、字符串实际值、字符串加扰值、批量写入操作批量){
final DBObject searchQuery=新的BasicDBObject(字段名、实际值);
final DBObject updateQuery=new basicdbobobject(“$set”,new basicdbobobject(fieldName,scrambledValue));
bulk.find(searchQuery).update(updateQuery);
}
定期更新代码

公共无效置乱(String collectionName、String fieldName){
最终列表distinctValues=getDistinctValues(collectionName,fieldName);
for(最终字符串实际值:distinctValues){
如果(!StringUtils.isEmpty(实际值)){
最终字符串扰码值=Get扰码值(实际值);
更新(collectionName、fieldName、actualValue、scrambledValue);
}
}
}
受保护的无效更新(字符串集合名、字符串字段名、字符串实际值、字符串加扰值){
final DBObject searchQuery=新的BasicDBObject(字段名、实际值);
final DBObject updateQuery=new basicdbobobject(“$set”,new basicdbobobject(fieldName,scrambledValue));
getCollection(collectionName).update(searchQuery,updateQuery);
}
批量更新API代码大约需要
1.5小时
,定期更新需要
2-3分钟

有人能解释一下这种行为吗。

您正在更新的集合已编制索引?没有,集合未编制索引您现在可以这样做吗?您正在更新之前读取数据,因为它没有索引,需要很长时间。为集合编制索引并尝试一下!希望它能比通常的更新工作得更好。祝你一切顺利!未编制索引的集合对这两种情况都有相同的影响。是的。。你是对的。但您没有在常规更新中搜索。在批量更新的情况下,您正在搜索和更新。由于您的集合未编制索引,因此它正在扫描整个集合并更新它。您可以使用explain命令检查性能。
public void scramble(String collectionName, String fieldName) {
    final List<String> distinctValues = getDistinctValues(collectionName, fieldName);
    final BulkWriteOperation bulk = mongoDb.getCollection(collectionName).initializeUnorderedBulkOperation();
    for (final String actualValue : distinctValues) {
        if (!StringUtils.isEmpty(actualValue)) {
            final String scrambledValue = getScrambledValue(actualValue);
            update(fieldName, actualValue, scrambledValue, bulk);
        }
    }
    bulk.execute();
}

protected void update(String fieldName, String actualValue, String scrambledValue, BulkWriteOperation bulk) {
    final DBObject searchQuery = new BasicDBObject(fieldName, actualValue);
    final DBObject updateQuery = new BasicDBObject("$set", new BasicDBObject(fieldName, scrambledValue));
    bulk.find(searchQuery).update(updateQuery);
}
public void scramble(String collectionName, String fieldName) {
    final List<String> distinctValues = getDistinctValues(collectionName, fieldName);
    for (final String actualValue : distinctValues) {
        if (!StringUtils.isEmpty(actualValue)) {
            final String scrambledValue = getScrambledValue(actualValue);
            update(collectionName, fieldName, actualValue, scrambledValue);
        }
    }
}

protected void update(String collectionName, String fieldName, String actualValue, String scrambledValue) {
    final DBObject searchQuery = new BasicDBObject(fieldName, actualValue);
    final DBObject updateQuery = new BasicDBObject("$set", new BasicDBObject(fieldName, scrambledValue));
    mongoDb.getCollection(collectionName).update(searchQuery, updateQuery);
}