Search code examples
iosobjective-ccore-dataoptimizationnsfetchrequest

Core Data fetch request optimization


I'm developing and application which needs to check if a string has been saved to the database or not. This may seem an easy operation but it needs half a second to return any response which I think is quite a lot. My question is if there is any way to reduce that time. Thanks for your interest.

This is my current code:

- (BOOL) isDeleted:(int)i {

    NSString *value = [NSString stringWithFormat:@"deleted.*.%i", i];

    MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];

    NSString *entityName = @"Deleted";
    NSEntityDescription *entityDesc = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDesc];

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"(deletedpics like %@)", value];
    [request setPredicate:pred];

    NSError *error;
    NSArray *objects = [context executeFetchRequest:request error:&error];

    BOOL returnBool = [objects count] >= 1 ? YES : NO;
    return returnBool;

}

Solution

  • One optimization is to replace

    NSArray *objects = [context executeFetchRequest:request error:&error];
    

    by

    [request setFetchLimit:1];
    NSUInteger count = [context countForFetchRequest:request error:&error];
    

    if you only want to check for the existence of objects.

    But I assume that the main performance problem is the wildcard search with LIKE, which is slower than searching with ==.

    Instead of storing the status and the picture number in one attribute as deleted.<status>.<picturenumber> (as you wrote in a comment) it would probably be better to use separate attributes status and picturenumber in the entity.

    Then you can search for a picture number with the predicate

    [NSPredicate predicateWithFormat:@"picturenumber == %d", i];
    

    which should be much faster. If necessary, you can additionally index that property (as @flexaddicted mentioned in a comment).