Print this page

Workaround for splitting one batch job into mutiple smaller batch jobs

Knowledge Article Number 000113364
Description If a user has a large number of records to execute in a batch class and batch class is taking a long time while processing records. User can split the query (which is returning records to process in batch class) into multiple queries so that these queries can be used in same Batch class, hence making the Batch class dynamic.
How we can break a query into multiple ones?
You can break the query using some criteria or if you want to break the query into two. we can use the following:
Suppose total number of records in account table is 50,000
Query first:
Select name from account limit 25,000
second query :
select name from account order BY createdDate DESC limit 25,000
By these queries we are covering all the records which we are covering in one query previously.
Why we use query in batch class??
we need to use SOQL query so that we can find whether the particular batch class is already executed or  not. If yes, we can execute the same batch class for the second query.
Note: First time when the batch class hasn't executed once, it will execute for the first query.
How to check for the batch class execution?
We have a object called "AsyncApexjob". We can use SOQL query on it to check for the particular class.
Example: SELECT Id FROM AsyncApexJob where ApexClassid='XXXXXXXXXXXXXX'
 ApexClassid is id of the batch class.
 If there is no value returned from the Query, we need to execute first query. IF returned, execute the second one.

Note : This is just a example to split queries. you can also split query using other criteria also.
How to use SOQL query in Batch class? 
As we already know that, we can only declare variables  in batch class(outside any method), therefore we cannot use any SOQL query inside the Batch class.
What we can do to overcome from this that we can create a separate class, in whose constructor we can implement our logic of SOQL queries.
Then we can declare the instance of the class in batch class. By using the variables of the class, we can declare the query parameter of the batch class.
Small example of batch class:
global class newbatchclass implements Database.Batchable<sObject>{

abc a = new abc();    // instance of my class
public String query=a.s;  //here s is the variable of the class which is sending the value to "query" dynamically on every execute. 

global Database.querylocator start(Database.BatchableContext BC){
            return Database.getQueryLocator(query);

global void execute(Database.BatchableContext BC, List<sObject> scope){

update accns;

global void finish(Database.BatchableContext BC){

Example of the class:
public class abc{
public string s;  //variable which will assign value to query on every execute
public integer n;
public abc(){
AsyncApexJob Ajob= new AsyncApexJob();
Ajob=[SELECT ApexClassId,completedDate FROM AsyncApexJob where apexclassID='01p90000001SUnCAAW' limit 1]; // to check whether the batch class has executed or not
s='Select id from account limit 2500';
s='Select id from account ORDER BY createdDate DESC limit 2500';
system.debug('Query number:'+n);
Note: 1) you need to execute the batch class twice , it will take the appropriate query automatically.
To execute, use: database.executebatch('name of your batch class');
2) Example taken over here is for twp queries , you can make it for n number of queries.

promote demote