Reputation: 355
I am doing a Core Data lightweight migration when users run the updated version of my app for the first time. The migration works fine but can be quite slow when the database is large, even when the migration really ought to be trivial and fast.
In particular, all I want to do is add a new entity to the data model, and the new entity is actually completely unrelated to any existing entities (no relationships to existing entities, except that both old and new entities are subclasses of NSManagedObject). Essentially, this operation should just be adding an empty table in SQL, no?
When the main.sqlite file has non-trivial size (say a few hundred megabytes), the resulting lightweight migration can take 5 seconds or much much more (see below) on my machine (OSX 10.10.1, about 2 year old Mac Mini).
In fact, in my experience, the name of the new entity affects the speed of the operation! I've been debugging by setting the launch arguments "-com.apple.CoreData.MigrationDebug 1" and "-com.apple.CoreData.SQLDebug 1" and it looks like I get SQL operations such as
2015-06-24 11:41:21.711 MyApp[517:14645] CoreData: sql: UPDATE ZENTITYNAMEHERE SET Z_ENT = ( CASE WHEN Z_ENT = 9 THEN 10 ELSE Z_ENT END ) WHERE Z_ENT IN (9)
for all entities that are later in alphabetical order compared to the newly inserted entity. For entities with lots of data these can take substantial time. Is this actually expected behavior?!
Giving the new entity a name that is latest in alphabetical order eliminates the above SQL commands, but the migration still takes many seconds to perform. It seems that Core Data actually duplicates the entire data on disk, as I am seeing temporary files with filenames such as .main.sqlite.migrationdestination_ in the same directory as main.sqlite and with roughly the same size. This seems entirely unnecessary just to add a new unrelated entity/table to the model, no?!
Is there some way to avoid this waste and make the migration fast (creating a new table should not take more than milliseconds I'd guess)?
Any help from resident Core Data gurus would be much appreciated!
(P.S. I'm using Xcode 6.1.1 if this is relevant.)
Upvotes: 0
Views: 142
Reputation: 80271
I think if you want to use the migration mechanism you are out of luck. Core Data will indeed copy all the data to a new store, and that can take considerable time.
One possible solution could be to create a second, separate store to contain the unrelated entity.
This adds more complexity and is clearly a trade-off but could be feasible. You will have to weigh if it is worth the trouble.
Upvotes: 1