Optimisation de cette requête de données de base

J'ai une entité dans Core Data nommée MusicInterest. Je dois en append 5000 à la fois et mon process actuel consiste à vérifier si MusicInterest existe déjà, sinon à en créer un nouveau.

Il semble que cela nécessite 5000 voyages au magasin pour voir si chaque titre existe. Il y a aussi, bien sûr, des voyages d'insertion, mais les 5000 requêtes sont ce qui me ralentit.

Chaque FacebookFriend aura plusieurs intérêts musicaux, et j'énumère à travers chacun d'eux en utilisant un tableau de titres de strings, appelant le code suivant.

Des idées pour optimiser cela?

+ (MusicInterest*) musicInterestForFacebookFriend:(FacebookFriend*)facebookFriend WithTitle:(NSSsortingng*)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:(NSSsortingng *)MusicTitle moc:(NSManagedObjectContext *)moc { // query to see if there NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MusicInterest"]; request.predicate = [NSPredicate predicateWithFormat:@"title == %@", [NSSsortingng ssortingngWithFormat:@"%@", MusicTitle]]; NSError *error = nil; NSArray *matches = [moc executeFetchRequest:request error:&error]; if (error) { NSLog(@"Error querying title in Music interest. Error = %@", error); } return matches; } 

METTRE À JOUR:

J'ai utilisé la design suggérée dans le guide de programmation Core Data et j'ai réduit mon time de 12 secondes à 4 secondes (encore besoin d'optimization dans d'autres domaines 🙂

Le guide ne comprend que la moitié de l'exemple de code – je pensais partager ma mise en œuvre complète:

 musicArray = [[music componentsSeparatedBySsortingng:@", "] 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++) { NSSsortingng *title = musicArray[i]; if (i < [musicInterestMatchingTitles count]) { MusicInterest *comparingMusicInterest = musicInterestMatchingTitles[i]; // compare each title if (![title isEqualToSsortingng: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]; 

Implémenter Find-or-Create de manière efficace dans le «Core Data Programming Guide» décrit un model qui pourrait être utile ici. L'idée de base est:

  • Triez votre list d'éléments que vous souhaitez insert / mettre à jour par un identifiant unique qui est également stocké dans la database.
  • Effectuez une requête de récupération unique qui récupère tous les objects de la database qui ont un ID de votre list, sortingés par le même ID.
  • Parcourez maintenant votre list et le tableau des éléments récupérés en parallèle, pour find quels éléments doivent être insérés et quels éléments existent déjà et peuvent être mis à jour.