2

在我的核心数据应用程序中插入 2000 条记录时,我遇到了性能问题。

数据作为一个大的 JSON 文件从服务器下载,并解析成一个 JSON 字典,这一切都很好,传递字典的时间也没什么……

问题是每次插入我的数据库需要的时间越来越长?

在我的导入过程中,我保存了每 100 个文档的上下文以减少内存,第一个文档需要 0.005434 毫秒来保存,最后一个文档需要 0.039297 毫秒来保存..

我在一个单独的线程中执行所有这些导入,其中包含一个全新的 ManagedContext,其中 undomanager 设置为 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.19s

1872 个文档 - 59.1 秒

所以,结论是我的 fetch 请求随着文档数量的增加而花费的时间越来越长.. 但这也是有道理的 :) 不知道为什么我之前没有想到这一点......所以现在解决方案是检查同步是否是第一个,然后在不获取任何现有文档的情况下导入文档。

/雅各布

4

1 回答 1

0

Based on your code, the issue has nothing to do with inserting anything. Nothing actually gets persisted to the database until you call the save method. I'm assuming the "...code that inserts the doc" is the code in the documentsWithDictionary:lastModifiedDate:inLevels:inManagedObjectContext: method. You are not actually inserting anything here, but creating a new ManagedObject in memory. However, you ARE querying the database every time you do this. As the number of records in the database grows, the query could take slightly longer to find a record of the given id.

Apple has outlined some good practices for efficiently importing large data sets: http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/coredata/Articles/cdImporting.html#//apple_ref/doc/uid/TP40003174-SW1

特别是,您将需要阅读“高效实施查找或创建”。按照他们的指南,您可以将数据库读取限制为每批记录一次,或者对您要导入的整个数据集只读取一次。

于 2012-05-18T15:59:33.437 回答