I’m running a very basic fetch request that returns about 2000 objects. I’m using an NSFetchedResultsController with a batchSize of 15.
predicate= [NSPredicate predicateWithFormat:@"ANY tags.tagName==%@", currentTagObject.tagName];
[fetchRequest setPredicate:predicate];
NSSortDescriptor *sort= [[NSSortDescriptor alloc] initWithKey:@"createDate" ascending:NO selector:@selector(compare:)];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:15];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:@"createDay" cacheName:nil];
The fetch request takes over 10 seconds though. I’ve enabled SQLite debugging so I can see what’s going on. I think it’s fetching all 2000 entities, with only 15 with actual values, then for some reason going through each and every of the 2000 objects and faulting them in.
During the fetch, these lines appear thousands of times:
2012-06-22 21:14:47.546 app[9227:707] CoreData: annotation: sql connection fetch time: 0.0107s
2012-06-22 21:14:47.551 app[9227:707] CoreData: annotation: total fetch execution time: 0.0171s for 15 rows.
2012-06-22 21:14:47.568 app[9227:707] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZAUTHOREMAIL, t0.ZAUTHORNAME, t0.ZCREATEDATE, t0.ZISGLOBAL, t0.ZISLOCKED, t0.ZISNEW, t0.ZISPENDINGDELETE, t0.ZISPENDINGSYNC, t0.ZLASTUPDATED, t0.ZLOCALLYMODIFIEDDATE, t0.ZMETALASTUPDATED, t0.ZNOTEID, t0.ZNUMBEROFCHILDREN, t0.ZPARENTAUTHOREMAIL, t0.ZPARENTNOTEID, t0.ZROOTAUTHOREMAIL, t0.ZROOTNOTEID, t0.Z4PENDINGADDNOTES, t0.Z4PENDINGREMOVENOTES FROM ZMBNOTEOBJECT t0 WHERE t0.Z_PK IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ORDER BY t0.ZCREATEDATE DESC LIMIT 15
...thousands more lines exactly similar to the three above
My table only shows 5 cells a time, so I have no idea why all the objects are being faulted in immediately. What could be causing this? Why would all the objects be faulted in immediately without me even scrolling my table? Can it be that they are being accessed somewhere, perhaps iterated? Does calling NSArray *fetchedObjects = fetchedResultsController.fetchedObjectscause all objects to be faulted by any chance?
Check out what it says in the documentation about
batchSize(my emphasis):So, clearly, according to this explanation, you get 2000/15 round trips to the store. That will certainly take some time. You need all the data because of your sort and the
ANYpredicate but you instructed the request to only get 15 at a time.Also, for completeness, from the previous comments: drop the
comparefrom your sort descriptor.