You cannot do much about the time it takes to move and delete objects in the database. However, you can do this in the background so that the user interface does not block.
For example, something like (the code assumes ARC - and was just printed - not compiled) ...
- (void)deleteAllLevelsInMOC:(NSManagedObjectContext*)moc {
Note that you can add a RootLevel object to your data model and give it a one-to-many relationship with first-tier objects. Then (as long as you have only one root object) all you have to do is delete one root object and it will delete everything else inside CoreData. If you have many FirstLevel objects, this will be the way to go.
Alternatively, you can connect your βnewβ context directly to the persistent store, make changes and view another context for change notifications.
By the way, if you use UIManagedDocument, you get this kind of background for free, because there is already a parent context running in its own queue, and all changes in the main context are transferred to the parent person in order to actually work with the database.
EDIT
You can do this manually, but you must disable the cascade rule. I found that I want CoreData to do as much as possible for me. This reduces my margin of error.
If you are already deleting the background thread, then how do you see performance issues? You must query during this deletion ... which means that you are using a MOC that does all the work.
You should learn a lesson from UIManagedDocument. You must have a MOC that runs in a private queue. He does all the real work. You have a child MOC that simply transfers the work of this work queue.
If you are actually requesting objects that are not in the graph that you are deleting, you can hang them on the serializing properties of the persistent storage coordinator. If so, you should consider either a separate coordinator, or just have two stores.
Thus, you can delete objects in your schedule as much as you want, but at the same time respond to requests for other objects.