2

I am trying to query list of records, make changes and update the same. I see two approaches here:

Approach 1:

 List<Account> listOfAccToUpdate=new List<Account>();
for(Account acc: [SELECT field1 FROM Account WHERE Rba__c=true]){
    acc.field1=true;
    listOfAccToUpdate.add(acc);
}
update listOfAccToUpdate;

Approach 2:

List<Account> listOfAccToUpdate=new List<Account>();
for(List<Account> accList: [SELECT field1 FROM Account WHERE Rba__c=true]){
    for(Account acc: accList){
        acc.field1=true;
    }
    if(listOfAccToUpdate.size()+accList.size()<=10000){
        listOfAccToUpdate.addAll(accList);
    }
    else{
        update listOfAccToUpdate;
        listOfAccToUpdate.clear();
        listOfAccToUpdate.addAll(accList)
    }
    
    
}

Question- Is Approach 2 better since we do not know if the query returns more than 10 k records. Also we may save on heap size on second approach, though syntactically I am doing a DML in a loop

1 Answer 1

4

Since there's a limit of 10k records per transaction, it doesn't matter if you limit yourself to 10,000 records at once. You're still limited to 10,000 rows. Your strategy should therefore be more like "if more than 10000 rows, jump to a queueable or batchable method".

In addition, your queries are limited to just 50,000 rows before a governor limit is breached (again, per transaction, not just per query), which will generally fit in heap space unless you query many fields per object, in which case, you might want to move to a smaller size, such as 1,000 rows per DML operation instead.

In general, if you're worried about a large data skew, fire off a batchable or queueable, otherwise don't worry about the differences. The for-record-list method is slightly more efficient, but what's even faster is to use the first method without copying the records:

 List<Account> listOfAccToUpdate=[SELECT field1 FROM Account WHERE Rba__c=true];
for(Account acc: listOfAccToUpdate){
    acc.field1=true;
}
update listOfAccToUpdate;

This loop has the best performance characteristics, as you avoid reallocating heap excessively. See this answer, this answer, this answer, this answer, this answer (not mine), this question (also not mine), this question (more optimization, not mine), and other questions for more performance-related questions.

You may note some contradictory answers; the exact performance characteristics of Salesforce tends to change over time, so doing your own testing is advisable, but even more importantly, don't worry about micro-optimizations, it may not actually matter in the long run, or might even be optimized away in a future release.

The only thing you should take away from this answer is that the 10k limit is a hard limit, so you must be prepared to branch off to a Queueable or Batchable to update more than 10k records if you're concerned about the possibility.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .