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
nagendra kumar 21nagendra kumar 21 

how to reduce the batch job running process.

hi everyone, how to reduce the batch run time ?? when I ran the batch it took 2 days to complete it which is a lot time for business to check the changes, is there any way we can reduce it ??
 
Best Answer chosen by nagendra kumar 21
David Zhu 🔥David Zhu 🔥
In your code, the batches is triggered in this method:
global void execute(SchedulableContext SC) {
        AccountStatusBatch  batch = new AccountStatusBatch ();
        Database.executeBatch(batch);
    }

By this, it uses default batch size 200. 
To increase the batch size, you may set the size number.
global void execute(SchedulableContext SC) {
        AccountStatusBatch  batch = new AccountStatusBatch ();
        Database.executeBatch(batch,1000);  //set batch size to 1000.
    }

When increaseing the size, it might get salesforce governor limits CPU time in the number is too big. You can try use 1000 first, if there is no issue, you may increase to 1500, or 2000. In theory, the size could be up to 10000 in your case. (you have DML in your code)
 

All Answers

AbhishekAbhishek (Salesforce Developers) 
Hi,

Normally Batch apex takes time to execute completely depends on the number of records involved in your batch class. 

However, you can reduce your time in these ways. 

1. Do less query: Do less query in your batch class, Try using Subquery in your query if you fetch records from parent to child. OR try to fetch parent record fields if you query from child to parent. 

2. Do less DML:  Do not write any DML statement inside the loop. create a list for that and Do DML outside the loop

3. Use Collections (list, Set, map) if possible required. 

4. Make your code bulky


Here is one more way to reduce time 

Instead of checking the condition inside the loop, You can query only filtered records that you need for example. 

Select id, name from user where isactive = true; 


For(User u : userlist){
    if(u.isactive == true);  // no need to write this line if you have already queried filtered records.
}



I hope you find the above solution helpful. If it does, please mark as Best Answer to help others too.

Thanks.
 
nagendra kumar 21nagendra kumar 21

hi Abhi, i not developer, but i got this task below is my code can you check on it and let me know :- 

 

global class AccountStatusBatch implements Database.Batchable<sObject> , Schedulable {
    //global class AccountStatusBatch implements Database.Batchable<sObject>  {
    global Database.QueryLocator start(Database.BatchableContext BC){
        String strRecordTypeName = 'Strategic_Supplier';
        String strQuery = 'Select Id,of_Participated_Divisions_c,of_Awarded_Divisionsc,Statusc,Account_Decision_Makerc,of_Divisions_ever_having_APc,Status_Reason_c from Account ';
        if(Test.isRunningTest() == false){
            strQuery += ' where RecordType.DeveloperName=:strRecordTypeName';
        }
        return Database.getQueryLocator(strQuery);
    }
    
    global void execute(Database.BatchableContext BC, List<Account> lstAcc){
        
        System.debug(lstAcc);
        for(Account  acc: lstAcc){
            System.debug(acc.Status__c);
            //1
            if(acc.of_Awarded_Divisions_c > 0 && acc.Statusc != 'Awarded' && acc.Statusc != 'Do Not Contact' && acc.Status_c != 'Ineligible' || Test.isRunningTest() == true ){
                acc.Status__c  = 'Awarded';
            }
            System.debug(acc.Status__c);
            //2
            if(acc.of_Awarded_Divisions_c == acc.of_Divisions_ever_having_APc && acc.Status_c == 'Awarded'  || Test.isRunningTest() == true ){
                acc.Status_Reason__c = 'Full Award';
            }
            System.debug(acc.Status__c);
            //3
            if(acc.of_Awarded_Divisions_c > 0 &&  acc.of_Awarded_Divisionsc < acc.of_Divisions_ever_having_APc && acc.Status_c == 'Awarded'  || Test.isRunningTest() == true ){
                acc.Status_Reason__c = 'Partial Award';
            }
            System.debug(acc.Status__c);
            //4
            if(acc.of_Awarded_Divisions_c == 0 &&  acc.status_c == 'Awarded' || Test.isRunningTest() == true  ){
                acc.Status__c = 'Participated';
                acc.Status_Reason__c = 'Partial Participation';
                system.debug(acc.Status__c);
            }
            System.debug(acc.Status__c);
            //5
            if(acc.of_Participated_Divisions_c > 0 &&  acc.statusc != 'Awarded' && acc.statusc != 'Participated' && acc.statusc != 'Do Not Contact' && acc.status_c != 'Ineligible' || Test.isRunningTest() == true  ){
                acc.Status__c = 'Participated'; 
            }
            System.debug(acc.Status__c);
            //6
            if(acc.of_Participated_Divisions_c == acc.of_Divisions_ever_having_APc &&  acc.Status_c == 'Participated' ){
                acc.Status_Reason__c = 'Full Participation';
            }
            System.debug(acc.Status__c);
            //7
            if(acc.of_Participated_Divisions_c > 0  && acc.of_Participated_Divisionsc < acc.of_Divisions_ever_having_APc &&   acc.statusc != 'Awarded' && acc.Status_c == 'Participated'|| Test.isRunningTest() == true  ){
                acc.Status_Reason__c = 'Partial Participation';
            }
            System.debug(acc.Status__c);
            //8
            if( acc.status_c == 'Participated' && acc.of_Participated_Divisionsc == 0 && acc.Account_Decision_Maker_c != null|| Test.isRunningTest() == true ){
                acc.Status_Reason__c = 'Decision Maker Identified';
                acc.Status__c = 'Working Right Contact';
            } 
            System.debug(acc.Status__c);
            //9
            if( acc.status_c == 'Participated' && acc.Account_Decision_Makerc == null && acc.of_Participated_Divisions_c == 0 || Test.isRunningTest() == true ){
                acc.Status_Reason__c = 'Attempted Contact';
                acc.Status__c = 'Prospecting';
            }
            System.debug(acc.Status__c);
            System.debug(acc.Status_Reason__c);
        }
        if(!lstAcc.isEmpty()){
            // update lstAcc;
            Database.update(lstAcc,false);
        }
    }
    global void execute(SchedulableContext SC) {
        AccountStatusBatch  batch = new AccountStatusBatch ();
        Database.executeBatch(batch);
    }
    global void finish(Database.BatchableContext BC){
        
    }
}

David Zhu 🔥David Zhu 🔥
In your code, the batches is triggered in this method:
global void execute(SchedulableContext SC) {
        AccountStatusBatch  batch = new AccountStatusBatch ();
        Database.executeBatch(batch);
    }

By this, it uses default batch size 200. 
To increase the batch size, you may set the size number.
global void execute(SchedulableContext SC) {
        AccountStatusBatch  batch = new AccountStatusBatch ();
        Database.executeBatch(batch,1000);  //set batch size to 1000.
    }

When increaseing the size, it might get salesforce governor limits CPU time in the number is too big. You can try use 1000 first, if there is no issue, you may increase to 1500, or 2000. In theory, the size could be up to 10000 in your case. (you have DML in your code)
 
This was selected as the best answer
Arvind_SinghArvind_Singh
Nagendra,

I looked into your code and what i could see that you are printing list and also printing status evrytime using System.debug everytime. Debug statment do not count against code limit but system count it against CPU time Limit and time taken to print log is way higher when you are doing operation on big database. Remove or comment out Debug and look at performce of batch.

Also, You need to look at your query also I would strongly suggest to extract record based on Index filter which internally return result faster and improve query performance. You can user RecordTypeId for above case. 

The platform automatically maintains indexes on the following fields for most objects.
RecordTypeId
Division
CreatedDate
Systemmodstamp (LastModifiedDate)
Name
Email (for contacts and leads)
Foreign key relationships (lookups and master-detail)
The unique Salesforce record ID, which is the primary key for each object 

Hope it helps. 
anita sharma 5anita sharma 5

Here are some of the different ways on how to reduce the run-time of batch program, which I have come across, worked on, and which would be helpful to all of you in some way or the other. This can be applied not only to the existing programs which take a lot of time but also can be applied before creating such kind of report programs. There are two kinds of reports: standard and custom created report programs.
1. Standard programs:
2. Custom programs:
itab[] = itab1[].  ~ would be faster
                         LOOP AT itab.               ~ will take time when comparing above statement.
                          APPEND itab TO itab1.
                         ENDLOOP.
Also, check for more: https://blogs.sap.com/2013/04/26/how-to-reduce-run-time-of-program/

Thanks,
​​​Beeboom (https://beeboom.co/)

nagendra kumar 21nagendra kumar 21

thank for your responses, i'm new to coding, I'm trying to understand what you said, 

can you modify the code and send back to me which would work to fast the batch job

AbhishekAbhishek (Salesforce Developers) 
Hi Nagendra,

If you need a developer please contact your account executive they guide you to professional services.

The professional services will fulfill your requirement(It's a paid service) 

Thanks.