function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
rodney white 1rodney white 1 

Apex trigger takes a lot of time to access items in list

I have a simple Contact trigger in a sandbox org that is exhibiting some serious performance issues. After doing some debugging it looks like the issue boils down to accessing the items inside Trigger.new list. I mean literally just doing this:
Contact c = Trigger.new[i]
is really slow.

For example, this code runs reasonably quickly (processing 1000 updates in about 30 seconds):
trigger MyTrigger on Contact (after insert, after update, before delete) {
    if (Trigger.isUpdate) {
        for (Integer i = 0; i < Trigger.new.size(); i++) {
            Integer dummy = 0;
        }
    }
}

Results from bulk data load (coming from the bulk job details page):
Total Processing Time (ms): 29370
API Active Processing Time (ms): 27229
Apex Processing Time (ms): 28852

However, this code takes about six minutes to run:
trigger MyTrigger on Contact (after insert, after update, before delete) {
    if (Trigger.isUpdate) {
        for (Integer i = 0; i < Trigger.new.size(); i++) {
            SObject o = Trigger.new[i];
        }
    }
}

Results from bulk data load:
Total Processing Time (ms): 321264
API Active Processing Time (ms): 319187
Apex Processing Time (ms): 893650

If I record the time required to access individual list items like this:
trigger MyTrigger on Contact (after insert, after update, before delete) {
    if (Trigger.isUpdate) {
        for (Integer i = 0; i < Trigger.new.size(); i++) {
            Long e = System.currentTimeMillis();
            SObject o = Trigger.new[i];
            Long s = System.currentTimeMillis();
            System.debug('time: ' + (e - s));
        }
    }
}

I see a lot of times around 400 milliseconds.

What's going on here? Does it really take that long to access an element in a list? Is there any way around this?
 
GovindarajGovindaraj
Hi Rodney,

Did you try like below,

for(Sobject o : trigger.new) {
      /* More logic */
}

*Here the cost for search in Trigger.new[i] is saved.

Thanks,
Govindaraj.S
Ravi PRavi P
Try this:
trigger MyTrigger on Contact (after insert, after update, before delete) {
    if (Trigger.isUpdate) {
        for (Conact con :Trigger.new) {
            Integer dummy = 0;
        }
    }
}
GovindarajGovindaraj
Hi,

Please keep this communtiy clean by closing solved cases.

Thanks,
Govindaraj.S
rodney white 1rodney white 1
Sorry it took me a while to respond. As I was trying the suggesions listed here, I noticed that the performace is much better than before. The import that used to take 6 minutes now runs in under 30 seconds. So I can no longer recreate the slow performance.

I'm not sure what could have caused that change. Are there any salesforce imposed limitations that we might have been running into earlier? We are not hitting our apex code or storage limits. Could there be anything else that could have caused the slow down?
 
mukesh guptamukesh gupta
Hi Rodney,

You could put your related record update logic into a before trigger.

You need to use before trigger (or more accurately, before the after trigger is run), and have related record update logic in an after trigger, then you potentially won't spend time doing more work that will just be rolled back (compared to if your related record update logic were in a before trigger)

when making a change to a record stored in trigger.new and/or trigger.newMap


if you fond this useful then, PLEASE MARK AS A BEST ANSWER!!

Regards
Mukesh