Consider the following 2 predicates that are filtered through the 5k + record store:
predicate1 = [NSPredicate predicateWithFormat:@"hidden == NO AND name BEGINSWITH[cd] %@", searchString]; predicate2 = [NSPredicate predicateWithFormat:@"name BEGINSWITH[cd] %@", searchString];
I included -com.apple.CoreData.SQLDebug to see the fetch request time:
predicate1: 0.4728s
predicate2: 0.0867s
Am I missing something? Both columns are indexed. Why does adding a simple boolean check slow down a fetch request?
EDIT : on request, output:
CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZHIDDEN, t0.ZID, t0.ZNAME, t0.ZRANK FROM ZARTISTINDEX t0 WHERE ( t0.ZHIDDEN = ? AND ( NSCoreDataStringSearch( t0.ZNAME, ?, 393, 0) OR NSCoreDataStringSearch( t0.ZNAME, ?, 393, 0))) ORDER BY t0.ZRANK DESC LIMIT 14
The rank column is also indexed. The reason I need this query to be faster than 0.5 s is because it is used for the autocomplete function. This query is executed every time a custom value changes the value of a certain text field.
EDIT 2 : adding more contextual information:
- (NSArray*)autocompleteSuggestions:(NSString*)searchString { NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"ArtistIndex" inManagedObjectContext:self.indexObjectContext]; [request setEntity:entity]; [request setFetchLimit:10]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"hidden == NO AND (name BEGINSWITH[cd] %@ OR name BEGINSWITH[cd] %@)", searchString, [NSString stringWithFormat:@"the %@", searchString]]; [request setPredicate:predicate]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"rank" ascending:NO]; [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; [sortDescriptor release]; NSArray *resultsArray = [self.indexObjectContext executeFetchRequest:request error:nil]; [request release]; return resultsArray; }
The ArtistIndex object has the following attributes:
- id (int32)
- name (string, indexed)
- rank (int32, indexed)
- hidden (BOOL, indexed)
Edit 3 : here are the full SQL outputs for the slow query (predicate1) and fast query (predicate2) with com.apple.CoreData.SQLDebug set to 3. More stringent tests led me to the following test times, which are better, but still have a difference of + 2x and really matter in the context of autocomplete suggestions. Or is it now a reasonable time difference?
predicate1: 0.3772s
predicate2: 0.1633s