2

I have one child object on account having lookup relationship, I want to update the average of some fields of child to parent, for this I wrote one after insert trigger on child. on doing bulk load I'm getting cpu time limit exception. How can I make this code more bulkify?

below is my code:

public void updateAccount(List<CustomObject> CustomObjectList){

    Set<Id> accIdSet = new Set<Id>();
    for(CustomObject per : CustomObjectList){
        accIdSet.add(per.Account__c);
    }

    List<Account> accList = [SELECT Id, (Select Id,Field1,Field2,Field3,
                                        Field4,Field5,Field6,
                                        Field7,Field8,Field9,Field910 from CustomObjectList__r ORDER BY CreatedDate DESC LIMIT 1) FROM Account where Id IN : accIdSet LIMIT 1000];

    List<Account> accountList = new List<account>();                                    

    for(Account acc : accList){

        if(acc.CustomObjectList__r.size() > 0){

            for(CustomObject per : acc.CustomObjectList__r){
                Account accObj = new Account();
                accObj.Id = acc.Id;
                accObj.Field1 = per.Field1;
                accObj.Field2 = per.Field2;
                accObj.Field3 = per.Field3;
                accObj.Field4 = per.Field4;
                accObj.Field5 = per.Field5;
                accObj.Field6 = per.Field6;
                accObj.Field7 = per.Field7;
                accObj.Field8 = per.Field8;
                accObj.Field9 = per.Field9;
                accObj.Field910 = per.Field910;

                accountList.add(accObj);
            }  
        }
    }

    update accountList;


    List<AggregateResult> accAverageList = [Select Account__c,AVG(Field11) avg1,AVG(Field22) avg2,
                                                AVG(Field33) avg3,AVG(Field44) avg4,
                                                AVG(Field55) avg5,AVG(Field66) avg6,
                                                AVG(Field77) avg7,AVG(Field88) avg8,AVG(Field99) avg9,
                                                AVG(Field100) avg99 from CustomObject where Account__c IN : accIdSet GROUP BY Account__c LIMIT 1000];
    List<Account> accountAvgList = new List<account>(); 

    For(AggregateResult agr : accAverageList){
        Account accObj = new Account();
        accObj.Id = (Id) agr.get('Account__c');
        accObj.Field11 = Integer.valueOf(agr.get('avg1'));
        accObj.Field22 = Integer.valueOf(agr.get('avg2'));
        accObj.Field33 = Integer.valueOf(agr.get('avg3'));
        accObj.Field44 = Integer.valueOf(agr.get('avg4'));
        accObj.Field55 = Integer.valueOf(agr.get('avg5'));
        accObj.Field66 = Integer.valueOf(agr.get('avg6'));
        accObj.Field77 = Integer.valueOf(agr.get('avg7'));
        accObj.Field88 = Integer.valueOf(agr.get('avg8'));
        accObj.Field99 = Integer.valueOf(agr.get('avg9'));
        accObj.Field100 = Integer.valueOf(agr.get('avg99'));

        accountAvgList.add(accObj);
    }   

    update accountAvgList;                                  
}
  • Use a nested map to reduce the lookup time. The nested for loop is consuming large process time and has very poor performance (e.g. 100 records by 100 records is 10,000 executions of code – TSmith Nov 23 '16 at 15:49
  • can you please share some example? what do you mean by nested map – salesforce Developer Nov 23 '16 at 15:50
  • Take a look at this post (force201.wordpress.com/2014/11/09/…). Great piece of writing! – TSmith Nov 23 '16 at 15:57
  • Not sure why do you need the first part of the code? Why you are copying fields1-10 from the custom_object to the account? – Liron C Nov 23 '16 at 16:32
0

You'll get a huge time savings by instantiating your records using name=value pairs:

Slow

Account record = new Account();
record.id = someValue;
record.Field1 = someValue1;
// etc.
accountList.add(record);

Fast

accountList.add(new Account(
    Id = someValue,
    Field1 = someValue1
    // etc.
));

You have a couple sections of your code where this pattern will greatly reduce your CPU Time.

The general application of this strategy would look something like the following:

Map<Id, Account> accounts = new Map<Id, Account>([/*first query*/]);
for (AggregateResult aggregate : [/*aggregate query*/])
{
    Account existingRecord = accounts.get((Id)aggregate.get('Account__c'));
    ChildObject__c child = existingRecord.Children__r[0];
    accountList.add(new Account(
        Id = existingRecord.Id,
        AggregateField1 = aggregate.get('Field1'),
        AggregateField2 = aggregate.get('Field2'),
        Field1 = child.Field1,
        Field2 = child.Field2
    );
}
  • Hi Adrian, Even after changing it, I'm getting same error – salesforce Developer Nov 23 '16 at 16:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.