Add Core Data Index to certain Attributes via migration
Asked Answered
M

2

28

For performance reasons, i want to set the Indexed Attribute to some of my entities. I created a new core data model version to perform the changes. Core Data detects the changes and migrates my model to the new version, however, NO INDEXES ARE GENERATED.

If I recreate the database from scratch, the indexes are there. I checked with SQLite Browser both on the iPhone and on the Simulator. The problem only occurs if a database in the prior format is already there.

Is there a way to manually add the indexes? Write some sql for that? Or am I missing something? I did already some more critical migrations, no problems there. But those missing indexes are bugging me.

Thanks for helping!

Mammary answered 1/2, 2010 at 17:44 Comment(2)
may I suggest to accept Scott answer? It works and it is clean.Quartzite
Sure, totally forgot about that. Thanks, Vincent and thx for the great answer to Scott!Mammary
A
57

I had the same problem.

According to the Core Data Model Versioning and Data Migration Programming Guide:

Core Data’s perspective on versioning is that it is only interested in features of the model that affect persistence.

Simply adding an index to an existing model property does not automatically trigger a migration since Core Data does not see your two model schemas as being different (an index does not affect persistence).

You can, however, cause Core Data to see your model as being changed by adding a Version Hash Modifier to your newly indexed attribute. This triggered lightweight migration to update my existing databases.

Atonic answered 5/7, 2010 at 21:44 Comment(5)
Fantastic. Solved it for me. I was going crazy with how slow core data was and indexes just didn't seem to help! For anyone who doesn't understand exactly what the above solution means ... create a new model version, click on the attribute you wish to add the index too, in the property window tick index, then look below for "version hash modifier", just enter any string like "change1". The speed difference is hugeSwollen
Once you added the indexing to the attribute and entered a version hash modifier, how can you check that the values are being indexed?Stowell
I guess this does not work anymore in 2013. CoreData couldn't perform lightweight migration and returned error.Floris
@Andy I don't know what error you got, but make sure you add a new model version rather than just editing the existing. While viewing the model: Xcode->Editor->Add Model Version. This should still work in 2013!Cattleman
The problem with changing the version hash modifier is it does A LOT more work than I intended: 1. Rename Table to TempTable. 2. Create new Table. 3. Copy all data from TempTable to Table. 4. Create ALL indexes. 5. Delete tempTable. --- All I want to do is create 1 new index on the existing table.Tuchun
N
0

What migration strategy did you use?

In XCode you can generate a mapping model, and view the changes that will occur, including indexing.

I suggest simply adding the mapping model, verifying the index changes are specified, and do the automatic lightweight migration:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,nil];
NSPersistentStore *migratedStore = [persistentStoreCoordinator addPersistentStoreWithType:nil configuration:nil URL:storeURL options:options error:&error];
migrationWasSuccessful = (migratedStore != nil);

The Persistent store coordinator will auto-discover the mapping model, and use it to perform the migration. It sounds like the run-time inferred model is not sensitive to applying indexes to entity properties.

Niigata answered 29/3, 2010 at 20:20 Comment(1)
i forgot to mention, those options were already enabled in my tests. I did not test it without those, though...Mammary

© 2022 - 2024 — McMap. All rights reserved.