Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8433001
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T06:16:17+00:00 2026-06-10T06:16:17+00:00

This has been asked before, but no solution described that is fast enough for

  • 0

This has been asked before, but no solution described that is fast enough for my app needs.

In the communications protocol we have set up, the server sends down a new set of all customers every time a sync is performed. Earlier, we had been storing as a plist. Now want to use Core Data.

There can be thousands of entries. Deleting each one individually takes a long time. Is there a way to delete all rows in a particular table in Core Data?

delete from customer

This call in sqlite happens instantly. Going through each one individually in Core Data can take 30 seconds on an iPad1.

Is it reasonable to shut down Core Data, i.e. drop the persistence store and all managed object contexts, then drop into sqlite and perform the delete command against the table? No other activity is going on during this process so I don’t need access to other parts of the database.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T06:16:19+00:00Added an answer on June 10, 2026 at 6:16 am

    Dave DeLong is an expert at, well, just about everything, and so I feel like I’m telling Jesus how to walk on water. Granted, his post is from 2009, which was a LONG time ago.

    However, the approach in the link posted by Bot is not necessarily the best way to handle large deletes.

    Basically, that post suggests to fetch the object IDs, and then iterate through them, calling delete on each object.

    The problem is that when you delete a single object, it has to go handle all the associated relationships as well, which could cause further fetching.

    So, if you must do large scale deletes like this, I suggest adjusting your overall database so that you can isolate tables in specific core data stores. That way you can just delete the entire store, and possibly reconstruct the small bits that you want to remain. That will probably be the fastest approach.

    However, if you want to delete the objects themselves, you should follow this pattern…

    Do your deletes in batches, inside an autorelease pool, and be sure to pre-fetch any cascaded relationships. All these, together, will minimize the number of times you have to actually go to the database, and will, thus, decrease the amount of time it takes to perform your delete.

    In the suggested approach, which comes down to…

    1. Fetch ObjectIds of all objects to be deleted
    2. Iterate through the list, and delete each object

    If you have cascade relationships, you you will encounter a lot of extra trips to the database, and IO is really slow. You want to minimize the number of times you have to visit the database.

    While it may initially sound counterintuitive, you want to fetch more data than you think you want to delete. The reason is that all that data can be fetched from the database in a few IO operations.

    So, on your fetch request, you want to set…

    [fetchRequest setRelationshipKeyPathsForPrefetching:@[@"relationship1", @"relationship2", .... , @"relationship3"]];
    

    where those relationships represent all the relationships that may have a cascade delete rule.

    Now, when your fetch is complete, you have all the objects that are going to be deleted, plus the objects that will be deleted as a result of those objects being deleted.

    If you have a complex hierarchy, you want to prefetch as much as possible ahead of time. Otherwise, when you delete an object, Core Data is going to have to go fetch each relationship individually for each object so that it can managed the cascade delete.

    This will waste a TON of time, because you will do many more IO operations as a result.

    Now, after your fetch has completed, then you loop through the objects, and delete them. For large deletes you can see an order of magnitude speed up.

    In addition, if you have a lot of objects, break it up into multiple batches, and do it inside an auto release pool.

    Finally, do this in a separate background thread, so your UI does not pend. You can use a separate MOC, connected to a persistent store coordinator, and have the main MOC handle DidSave notifications to remove the objects from its context.

    WHile this looks like code, treat it as pseudo-code…

    NSManagedObjectContext *deleteContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateConcurrencyType];
    // Get a new PSC for the same store
    deleteContext.persistentStoreCoordinator = getInstanceOfPersistentStoreCoordinator();
    
    // Each call to performBlock executes in its own autoreleasepool, so we don't
    // need to explicitly use one if each chunk is done in a separate performBlock
    __block void (^block)(void) = ^{
        NSFetchRequest *fetchRequest = //
        // Only fetch the number of objects to delete this iteration
        fetchRequest.fetchLimit = NUM_ENTITIES_TO_DELETE_AT_ONCE;
        // Prefetch all the relationships
        fetchRequest.relationshipKeyPathsForPrefetching = prefetchRelationships;
        // Don't need all the properties
        fetchRequest.includesPropertyValues = NO;
        NSArray *results = [deleteContext executeFetchRequest:fetchRequest error:&error];
        if (results.count == 0) {
            // Didn't get any objects for this fetch
            if (nil == results) {
                // Handle error
            }
            return;
        }
        for (MyEntity *entity in results) {
            [deleteContext deleteObject:entity];
        }
        [deleteContext save:&error];
        [deleteContext reset];
    
        // Keep deleting objects until they are all gone
        [deleteContext performBlock:block];
    };
    
    [deleteContext preformBlock:block];
    

    Of course, you need to do appropriate error handling, but that’s the basic idea.

    Fetch in batches if you have so much data to delete that it will cripple memory.
    Don’t fetch all the properties.
    Prefetch relationships to minimize IO operations.
    Use autoreleasepool to keep memory from growing.
    Prune the context.
    Perform the task on a background thread.

    If you have a really complex graph, make sure you prefetch all the cascaded relationships for all entities in your entire object graph.

    Note, your main context will have to handle DidSave notifications to keep its context in step with the deletions.

    EDIT

    Thanks. Lots of good points. All well explained except, why create the
    separate MOC? Any thoughts on not deleting the entire database, but
    using sqlite to delete all rows from a particular table? – David

    You use a separate MOC so the UI is not blocked while the long delete operation is happening. Note, that when the actual commit to the database happens, only one thread can be accessing the database, so any other access (like fetching) will block behind any updates. This is another reason to break the large delete operation into chunks. Small pieces of work will provide some chance for other MOC(s) to access the store without having to wait for the whole operation to complete.

    If this causes problems, you can also implement priority queues (via dispatch_set_target_queue), but that is beyond the scope of this question.

    As for using sqlite commands on the Core Data database, Apple has repeatedly said this is a bad idea, and you should not run direct SQL commands on a Core Data database file.


    Finally, let me note this. In my experience, I have found that when I have a serious performance problem, it is usually a result of either poor design or improper implementation. Revisit your problem, and see if you can redesign your system somewhat to better accommodate this use case.

    If you must send down all the data, perhaps query the database in a background thread and filter the new data so you break your data into three sets: objects that need modification, objects that need deletion, and objects that need to be inserted.

    This way, you are only changing the database where it needs to be changed.

    If the data is almost brand new every time, consider restructuring your database where these entities have their own database (I assume your database already contains multiple entities). That way you can just delete the file, and start over with a fresh database. That’s fast. Now, reinserting several thousand objects is not going to be fast.

    You have to manage any relationships manually, across stores. It’s not difficult, but it’s not automatic like relationships within the same store.

    If I did this, I would first create the new database, then tear down the existing one, replace it with the new one, and then delete the old one.

    If you are only manipulating your database via this batch mechanism, and you do not need object graph management, then maybe you want to consider using sqlite instead of Core Data.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This is a question that has been asked before, but unfortunately no solution seems
This has been asked before , but even after implementing that solution, problems remain.
This question has been asked before but the accepted solution (given by the question
Sorry if this has been asked before, but I couldn't find a solution to
I'm sure this has been asked before, but I couldn't find a working solution
I realize that this question has been asked before - but none of the
While it seems that this has been asked many times before, but there's a
This has been asked once before but that didn't work for me at all.
This question has been asked before, but none that I have reviewed give a
I know this question has been asked before, but non of the solutions solve

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.