0

I have the following code:

global class ProcessLinkBetweenWorlds implements Database.Batchable<sObject>, Database.Stateful {

    global Integer recordsProcessed = 0;
    global List<Match_Holder__c> matchList = new List<Match_Holder__c>();
    global List<Case> caselist = ProcessLinkCases.listCase();
    Set<String> caseConcat = new Set<String>();

    global Database.QueryLocator start(Database.BatchableContext bc) {
        for (Case c : caselist){
            caseConcat.add(c.Concat_ID__c);
        } 

        return Database.getQueryLocator(       
            'Select PersonContactId,concat_ID__c,PersonEmail, Name from Account ' +
            'where PersonEmail != Null And IsPersonAccount = True And Is_Master_Record__c = True ORDER BY CreatedDate DESC  '                   
        );    
    }

    global void execute(Database.BatchableContext bc, List<Account> scope){
        for(Account a : scope) {

            for(Case c : caseList ) {

                if(c.Concat_Id__c == a.Concat_Id__c) {
                    Match_Holder__c match = new Match_Holder__c();
                    match.Name = 'Match!: ' + a.Id + ' | ' + c.Id;
                    matchList.add(match);
                }
            }
        }
        upsert matchList;
    }    

    global void finish(Database.BatchableContext bc){
        System.Debug('Match list size: ' + matchList.size());
    }    
}

I'm trying to optimize this Batch Apex class, it currently runs on 700,000+ records so any gain I can get would be beneficial.

I can't think of another way to check if the fields on the two objects match without the nested for loops for account scope and case list. Is there any way I can gain some speed and maybe get my goverenor limit usage reduced?

1 Answer 1

0

So you can do like this

map<Id, Account> mapConcatIdToAccount = new map<Id, Account>(); 
// first create a map with Concat Id to Account record  
for(Account a : scope) 
{
    if(a.Concat_Id__c != null)
    {
        mapConcatIdToAccount.put(a.Concat_Id__c, a); 
    }
}

// now based on concat ids query case records and create Match_Holder__c 
for(Case objCase: [SELECT Id, Concat_Id__c FROM Case WHERE Concat_Id__c IN: mapConcatIdToAccount.keyset()])
{
    Match_Holder__c match = new Match_Holder__c();
    match.Name = 'Match!: ' + mapConcatIdToAccount.get(objCase.Concat_Id__c ).Id + ' | ' + objCase.Id;
    matchList.add(match);

}
upsert matchList;

This way you can get only those contacts which are in related to Accounts which are in currently in execute methods.

2
  • Thanks Ratan, however I get invalid field objCase for SObject case error upon compile. (The objCase.objCase)
    – user24634
    Jul 29, 2016 at 10:32
  • @SamCousins ahh my bad typo.. it should be mapConcatIdToAccount.get(objCase.Concat_Id__c ).Id
    – Ratan Paul
    Jul 29, 2016 at 10:34

You must log in to answer this question.