在我的 Core Data 应用程序中插入 2000 条记录时,我对性能有疑问。
数据从服务器下载为一个大的JSON文件,并解析成一个JSON字典,这一切都很好,通过字典的时间不算什么......
问题是每次插入我的数据库需要越来越长的时间?
在导入过程中,我保存每 100 个文档的上下文以保持内存不足,第一个文档需要 0.005434ms 来保存,最后一个文档需要 0.039297ms 来保存。
我正在一个单独的线程中执行所有这些导入,该线程具有全新的托管上下文,撤消管理器设置为nil。
这是贯穿字典中所有文档的循环
NSArray *docs = [docsData objectForKey:@"docs"];
for(NSDictionary *doc in docs){
if(counter++ % 100){
[context save:nil];
}
NSDate *start = [NSDate date];
[Document documentWithDictionary:doc lastModifiedDate:[NSDate date] inLevels:nil inManagedObjectContext:context];
NSDate *end = [NSDate date];
NSLog(@"time used pr doc = %f",[end timeIntervalSinceDate:start]);
}
[context save:nil];
这是插入文档的代码
NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Document"];
req.predicate = [NSPredicate predicateWithFormat:@"id = %@", [data valueForKey:@"id"]];
NSArray *matches = [context executeFetchRequest:req error:&error];
if(matches){
if([matches count]){
document = [matches lastObject];
}else {
document = [NSEntityDescription insertNewObjectForEntityForName:@"Document" inManagedObjectContext:context];
}
}
有人可以阐明为什么插入时间越来越长吗?
在模拟器中,使用的时间pr doc几乎是恒定的,但在手机上不是?
这可能是一个小问题,但由于我可以在数据库中有 2000 到 30000 条记录,这实际上成为大量导入的一个因素。
非常感谢:)
/雅 各
更新-----
在数据库中仅执行插入后,即没有获取现有记录,这就是时间。
使用获取:
1100 个文档 - 54.6 秒
2349 文档 - 194.9 秒
1872 文档 - 222.1 秒
没有获取。
1100 个文档 - 34.4 秒
2349 文档 - 74.19 秒
1872 文档 - 59.1 秒
所以,结论是这是我的获取请求,随着文档数量的增加,需要的时间越来越长......但这也是有道理的:)不知道为什么我没有早点想到这一点...因此,现在的解决方案是检查同步是否是第一个同步,然后在不获取任何现有文档的情况下导入文档。
/雅 各
根据您的代码,该问题与插入任何内容无关。在调用 save 方法之前,实际上不会将任何内容保存到数据库中。我假设"...插入文档的代码"是文档中的代码WithDictionary:lastModifiedDate:inLevels:inManagedObjectContext: 方法。您实际上并没有在此处插入任何内容,而是在内存中创建新的托管对象。但是,每次执行此操作时,您都在查询数据库。随着数据库中记录数的增长,查询可能需要稍长的时间才能找到给定 id 的记录。
Apple 概述了一些高效导入大型数据集的良好做法: http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/coredata/Articles/cdImporting.html#//apple_ref/doc/uid/TP40003174-SW1
特别是,您需要阅读"有效地实施查找或创建"。按照他们的准则,您可以将数据库读取限制为每批记录一次,或者仅对要导入的整个数据集进行一次读取。