5

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 o = Trigger.new[i] appears to be 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 execute SObject o = Trigger.new[i] using System.currentTimeMillis() 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? I thought maybe I could convert it to an actual array but apparently toArray() is not a method that the Salesforce version of List supports.

I also find it odd the the Apex Processing Time value is greater than the Total Processing Time value but maybe that's a separate issue.

Update 1

This is pure speculation, but this org has a lot of customizations on the Contact record, including several formula fields. I'm wondering if, as a performance optimization, you aren't working with a "live" Contact record in the trigger until you access it from the Trigger.new list. Maybe it's taking a while to pull the Contact record out of Salesforce's database and compute all the formula fields on the fly. Just a theory...

Update 2

Somebody suggested that I try this:

trigger MyTrigger on Contact (after insert, after update, before delete) {
    if (Trigger.isUpdate) {
        for (Integer i = 0; i < Trigger.new.size(); i++) {
            if (Trigger.new[i] == null) {
            }
        }
    }
}

So the code is still access the List it's just not assigning it to anything. Doing this does address the performance issue (though it's not useful code). Not 100% sure why that is, something about the assignment to a variable is causing the issue. Maybe a copy of some sort is occurring? Anyway, it's another data point.

  • Where are you getting these numbers? – Adrian Larson Feb 5 at 23:50
  • 2
    @AdrianLarson - (presumably) Source of the statistics: View Bulk Data Load Job Details – Mark Pond Feb 6 at 0:09
  • @AdrianLarson those numbers are from the Bulk Data Load jobs results page. – d512 Feb 6 at 15:43
  • 1
    Sandboxes are lot slower than prod, might be that – Pranay Jaiswal Feb 6 at 15:59
  • 1
    @d512 have you enabled Skinny Tables in your org? Also worth raising a case with SF – Pranay Jaiswal Feb 6 at 20:18

Your Answer

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

Browse other questions tagged or ask your own question.