[SalesForce] Mass Deletion Of (most) Records (in Sandbox) (100 million+)

If someone has a better way of doing this, feel free to share. I'm not playing the role of developer any longer. However, we have an Object with over 100mil records in it, which is over our limit, and when we make a Full Sandbox, it breaks our ability to create records (in that Sandbox).

I need to loop this code. The FIRST and LAST LINES ("KeepGoing") is the questionable part that I'm writing in pseudo-code. Help?!? I don't care if it's a Do While or anything else. I'm trying to avoid doing a Count, then inside an If, doing the List separately (double the queries) (not even sure that would solve this…).

The code WITHOUT the KeepGoing lines works fine.

:KeepGoing

List<et4ae5__IndividualEmailResult__c>
    recLst = [select id from et4ae5__IndividualEmailResult__c limit 10000] ;

if( recLst.size() == 10000 ) {
    delete recLst; 
    goto KeepGoing;       }

Note: The 100mil records are temporary; this is unfortunately an immediate concern until they are trimmed officially. I also recognize that if the Object recsize is at any point literally 10k records, the last of the records will be deleted. No problem.

Another way of doing this could be: How do I do a COUNT (without a Query hopefully) of the object named above? I could encapsulate the whole thing in a Do While routine based on that Count, yes?

Do While ( et4ae5__IndividualEmailResult__c.count() > 30000 ) {

    List<et4ae5__IndividualEmailResult__c>
        recLst = [select id from et4ae5__IndividualEmailResult__c limit 10000] ;

    if( recLst.size() == 10000 ) {
        delete recLst; }

}

My code, as always, may be pseudo…

Update 2:     Just tried the following code, but it doesn't like that ultimately it's doing more than 10k at a time…

Integer loopNum = 0;

Do {

  List<et4ae5__IndividualEmailResult__c>
    recLst = [select id from et4ae5__IndividualEmailResult__c limit 10000] ;

  if( recLst.size() == 10000 ) { delete recLst; }

  loopNum++;

} While ( loopNum <= 10 );

Best Answer

Write a chained batchable class:

public class KillMostBatch implements Database.Batchable<SObject> {
    public Database.QueryLocator start(Database.BatchableContext context) {
        return Database.getQueryLocator([SELECT Id FROM MyObj__c LIMIT 20000000]);
    }
    public void execute(Database.BatchableContext context, MyObj__c[] scope) {
        if(scope.size()==200) {
            delete scope;
        }
    }
    public void finish(Database.BatchableContext context) {
        if([SELECT Count() FROM MyObj__c LIMIT 1]==1) {
            Database.executeBatch(this, 200);
        }
    }
}

This will leave at most 200 records. Yes, if it's an even multiple of 200, you'll be completely wiped out. This code will continue to eat all available records until less than 200 remain. Your recycle bin will be full, expect permanent loss.

Related Topic