为什么核心数据插入需要的时间越来越长



在我的 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

特别是,您需要阅读"有效地实施查找或创建"。按照他们的准则,您可以将数据库读取限制为每批记录一次,或者仅对要导入的整个数据集进行一次读取。

最新更新