Core Data Performance with Single Parent Entity

Core Data Performance with Single Parent Entity

Last year I worked on a project that did the same thing, we stored everything in core data and everything in core data inherited from a single class which had some common attributes.

We had somewhere between 1k - 10k records in core data and performance degraded to the point where we rewrote it and removed the common ancestor. As I recall simple searches were taking multiple seconds, and insertions / updates were pretty crappy too. It was only after things had gotten painfully slow that we cracked the db open and noticed under the covers core data was storing everything in one table.

Sorry I don't remember specific numbers, the big takeaway was we had to redo it because it was too slow, and not too slow like too slow for high frequency trading but too slow like the app crashed on load when trying to populate the initial view out of core data.

So, with the grain of salt that this was on older iOS and older hardware, I would say definitely do not do this.

Core data performances: when all entities inherit from the same parent entity

It will affect performance, but how much depends on how much commonality there is between the objects and how many objects you have. If there is little commonality and you don't need associated class inheritance of your managed object subclasses then making everything a child of the same entity isn't very useful. Use Instruments to check what's going on. Performance issues could be caused by other things such as your fetch request structure and batch size.

Using Parent Entity in CoreData Models

the Reverend,

While your schema can dramatically affect your performance, added columns to rows in a table is not your performance problem. Traversing complex relations and managing large BLOBs is your performance problem.

Yes, I use the entity inheritance. Yes, it is fast. Yes, it has allowed me to make a sane model. That said, the conventional OOP wisdom these days is to limit the depth of your inheritance hierarchies. This is probably a good idea when using Core Data. Composition of objects/entities is your friend.

Andrew

Core Data parent Entity

How about something simple like this (which assumes that isBookmarked is a boolean):

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Document" inManagedObjectContext:context];
// This may not be the most elegant way of using a boolean in a predicate, but…

NSNumber *numIsBookmarked = [NSNumber numberWithBool:YES];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isBookmarked == %@", numIsBookmarked];
NSFetchRequest *request = [[NSFetchRequest alloc] init];

[request setEntity: entityDescription];
[request setPredicate: predicate];
[request setResultType: NSManagedObjectResultType];

NSError *error = nil;
NSArray *results = [contextMain executeFetchRequest:request error:&error];

if (error)
{
// deal with the error
}

[request release];

After which you would check for which subclass was fetched:

for (NSManagedObject *obj in results)
{
if ([obj isKindOfClass:[Poem class]])
{
// do whatever
}
else if ([obj isKindOfClass:[Article class]])
{
// do whatever
}
}

(Alternatively, if several of the subclassed MOs implement the same method, it might be more efficient to do a respondsToSelector: test.)

That doesn’t work?

Set parent entity defined in bundled Core Data model

I would strongly recommend against this design. If all entities inherit from a single entity then your entire Core Data SQLite data structure will existing a single table. The performance cost for this is quite simply huge.

It is not possible to make the data modeler aware of the bundled data model.

Update

There is a difference between subclasses and sub-entities. There is nothing wrong with Subclassing. Creating sub-entities, however, is quite different and is designed to solve a different problem. Sub-entities are meant to intentionally combine so entities so that they share a common root and share a common set of properties or relationships. The cost of that is that they also share a common table. Which in the situation that they are intended for is not a significant cost.

The thread you referenced confused subclasses and sub-entities. They are not the same and they do not even need to align.

Trying to have an entire data model be sub-entities of a single parent entity is not the intended use of that feature of Core Data. It will cause horrific performance penalties and eventually stop your application from working. You would be better off working from a different design. For example, you could force them to subclass from your class which then subclasses NSManagedObject and do what you need to do in that subclass. You could further require an attribute to exist in each entity so that you can complete your goal.

mogenerator works in that vein (although it does not require an attribute to exist in the entities). There are also syncing frameworks that work off a similar design. They require that each entity have a unique identifier key, etc.

You could go even further and not necessarily require an attribute but instead require that the subclasses define a unique identifier so that you framework can uniquely identify each instance of an entity. You could then work with that uniqueID without requiring its definition be specific (a string, a number, etc.).

Prevent Core Data From Combining Entities into One Table

I did measurements and CoreData's performance is totally degraded when using inheritance on real (~50000 objects, 20+ classes, each having ~5 relationships, most of them to-many) data. I do not use CD for toy apps with 1000 objects - it's a real huge app and performance penality is unjustified. Even worse, creating small objects takes lots of ssd and memory space because of this stupid implementation.

The only real solution (i DO NEED inheritance) is to replace the default sqlite persistent store with manual implementation using NSIncrementalStore from iOS 5 and up. However, fetch request to SQL translation and model updates are really hard to implement.

And yes, I know that core data is not an SQL. But I expect it to work comparably fast when dealing with lots of data - otherwise it would be stupid to ever use it in real world apps.

Core Data: Abstract Entity in Fetch Request

You can definitely use that approach.

From Apple's Core Data Programming guide:

Entity inheritance works in a similar way to class inheritance; and is useful for the same reasons. If you have a number of entities that are similar, you can factor the common properties into a superentity, also known as a parent entity. Rather than specifying the same properties in several entities, you can define them in one entity, and the subentities inherit them. For example, you might define a Person entity with attributes firstName and lastName, and subentities Employee and Customer, which inherit those attributes.



Related Topics



Leave a reply



Submit