Re: Core Data fetch performance
Re: Core Data fetch performance
- Subject: Re: Core Data fetch performance
- From: Hunter Hillegas <email@hidden>
- Date: Sun, 11 Nov 2012 09:57:29 -0800
Do you have keyShadow set as indexed in the model? If not, you probably want to give that a try.
If you have all of the keys up front (i.e. this is a big batch update or insert from the Web Service data), you might consider loading all of the records at once and then using a predicate to find what you need. Something like:
//load all possible matches at once
NSFetchRequest *possibleEventsFetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"MissionEvent"];
[possibleEventsFetchRequest setPredicate:[NSPredicate predicateWithFormat:@"keyShadow IN %@", allPossibleKeyShadows]];
NSArray *possibleEvents = [self.managedObjectContext executeFetchRequest: possibleEventsFetchRequest error:nil];
//create a filter predicate
NSPredicate *indexMatchPredicate = [NSPredicate predicateWithFormat:@"keyShadow == %ld", inMEP.mId];
//this now happens in memory
NSManagedObject *matchingObject = [[possibleEvents filteredArrayUsingPredicate: indexMatchPredicate] lastObject];
Hunter
On Nov 11, 2012, at 6:42 AM, Rick Mann <email@hidden> wrote:
> I'm seeing a substantial degradation in Core Data fetch performance after just a few thousand objects, in the simulator on a beefy MacBook Pro.
>
> My app loads data from the web, then uses an integer key in each downloaded record to find the local record in Core Data. So I do a lot of queries like this:
>
> {
> NSFetchRequest* req = [[NSFetchRequest alloc] init];
> req.fetchLimit = 1;
>
> NSManagedObjectContext* moc = self.managedObjectContext;
> NSEntityDescription* entity = [NSEntityDescription entityForName: @"MissionEvent"
> inManagedObjectContext: moc];
> req.entity = entity;
>
> NSPredicate* pred = [NSPredicate predicateWithFormat: @"keyShadow == %ld", inMEP.mId];
> req.predicate = pred;
>
> NSError* error = nil;
> NSArray* events = [self.managedObjectContext executeFetchRequest: req error: &error];
> ...
> }
>
> Basically, I query, the insert, over and over. As the number of records grows from 0 to 6000, the time it takes to execute this query grows from about 0.0007 s to about 0.0126 s. Indexing is on for keyShadow:
>
> sqlite> explain query plan SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZCLOCKSHADOW, t0.ZDESC, t0.ZDISABLEDSHADOW, t0.ZDURATIONSHADOW, t0.ZKEYSHADOW, t0.ZLASTMODIFIED, t0.ZNAME, t0.ZSEQUENCESHADOW, t0.ZTIMESHADOW, t0.ZTYPESHADOW, t0.ZMISSION FROM ZMISSIONEVENT t0 WHERE t0.ZKEYSHADOW = ?
> ...> ;
> sele order from deta
> ---- ------------- ---- ----
> 0 0 0 SEARCH TABLE ZMISSIONEVENT AS t0 USING INDEX ZMISSIONEVENT_ZKEYSHADOW_INDEX (ZKEYSHADOW=?) (~10 rows)
>
> This seems like pretty poor performance. Is this the best I can hope for?
>
> Thanks,
>
> --
> Rick
>
>
>
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden