优化此核心数据请求

我在Core Data中有一个名为MusicInterest的实体。 我必须一次添加5000个左右,而我现在的过程是查询MusicInterest是否已经存在,如果没有创build新的。

看来这需要5000次去商店看看每个标题是否存在。 当然,也有插入行程,但5000个查询是减慢我的速度。

每个Facebook的朋友将有多个音乐兴趣,我通过使用一个string标题数组,每一个枚举,调用下面的代码。

任何想法如何优化这个?

+ (MusicInterest*) musicInterestForFacebookFriend:(FacebookFriend*)facebookFriend WithTitle:(NSString*)musicTitle UsingManagedObjectContext:(NSManagedObjectContext*)moc { // query to see if there NSArray *matches = [self queryForMusicTitle:musicTitle moc:moc]; if (([matches count] >= 1)) { // NSLog(@"Music already in database"); MusicInterest *existingMusic = [matches lastObject]; [existingMusic addLikedByObject:facebookFriend]; return [matches lastObject]; } else { // create new Music Interest MusicInterest *newMusic = [NSEntityDescription insertNewObjectForEntityForName:@"MusicInterest" inManagedObjectContext:moc]; newMusic.title = musicTitle; [newMusic addLikedByObject:facebookFriend]; return newMusic; } } + (NSArray *)queryForMusicTitle:(NSString *)MusicTitle moc:(NSManagedObjectContext *)moc { // query to see if there NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MusicInterest"]; request.predicate = [NSPredicate predicateWithFormat:@"title == %@", [NSString stringWithFormat:@"%@", MusicTitle]]; NSError *error = nil; NSArray *matches = [moc executeFetchRequest:request error:&error]; if (error) { NSLog(@"Error querying title in Music interest. Error = %@", error); } return matches; } 

更新:

我采用了Core Data编程指南中提出的devise,将时间从12秒缩短到4秒(在其他方面仍需要一些优化:)

指南只包括一半的示例代码 – 我想我会分享我的完整实现:

 musicArray = [[music componentsSeparatedByString:@", "] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { if (obj1 > obj2) return NSOrderedDescending; else if (obj1 < obj2) return NSOrderedAscending; return NSOrderedSame; }]; if (musicArray) { NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"MusicInterest"]; [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"title IN %@", musicArray]]; [fetchRequest setSortDescriptors: @[[[NSSortDescriptor alloc] initWithKey: @"title" ascending:YES]]]; NSError *fetchError = nil; NSArray *musicInterestMatchingTitles = [backgroundContext executeFetchRequest:fetchRequest error:&fetchError]; if ([musicArray count] > 0) { // walk musicArray and musicInterestsMatchingTitles in parallel for (int i = 0; i < [musicArray count]; i++) { NSString *title = musicArray[i]; if (i < [musicInterestMatchingTitles count]) { MusicInterest *comparingMusicInterest = musicInterestMatchingTitles[i]; // compare each title if (![title isEqualToString:comparingMusicInterest.title]) { // if it doesn't exist as a ManagedObject (a MusicInterest), create one MusicInterest *musicInterest = [MusicInterest createNewMusicInterestUsingManagedObjectContext:backgroundContext]; musicInterest.title = title; [musicInterest addLikedByObject:friend]; } else { // otherwise, just establish the relationship [comparingMusicInterest addLikedByObject:friend]; } } else { // if there are no existing matching managedObjects, create one MusicInterest *musicInterest = [MusicInterest createNewMusicInterestUsingManagedObjectContext:backgroundContext]; musicInterest.title = title; [musicInterest addLikedByObject:friend]; } } } } }]; [self saveBackgroundContext:backgroundContext]; 

在“核心数据编程指南”中高效地实现查找或创build描述了一个在这里可能有用的模式。 基本的想法是:

  • 对您想要插入/更新的项目列表进行sorting,该列表也存储在数据库中。
  • 执行一个单一的提取请求 ,从数据库中提取所有对象,并从您的列表中获取一个id,并按照相同的IDsorting。
  • 现在并行遍历你的列表和获取的项目数组,找出哪些项目已经被插入,哪些项目已经存在并且可以被更新。