I have a read query in a batch class which in orgs with a lot of data can bring back over 50,000 records and violate the governor limit. My question is it possible to do a count query, realise that the records is over 50,000 and then split the query up into a numer of separate queries to lower the probability of the governor limit being violated?
- Anybody can ask a question
- Anybody can answer
- The best answers are voted up and rise to the top
Regarding "If I can set the batch size dynamically. can I?" comment:
You can decide upfront. Use optional param of the method that kicks off the batch.
Again - planning upfront - can you maybe use a helper object with a COUNT rollup summary of the stuff you want to iterate over? This needs a master-detail between the two though so might be not working for your case.
You can also make a "poor man's counter" yourself, keeping count of records in a custom setting (updating it with after insert triggers). Or read about Analytic Snapshots.
If we could see the query or know a bit more about your context a bit more, you might get better advice. Fastest way to chunk the data is to use this extra parameter as it requires no further setup & logic.
You don't need to do any sort of count query or roll-up summary at all --- a single Batch Apex class could iterate over millions of records if it needed to.
All of the answers and comments so far seem to be ignoring / forgetting some fundamental characteristics of Batch Apex and its Governor Limits:
And this can be called like this:
For scenario 1, where you want to loop over all Contact records for each Account, you want to explicitly limit the scope of each batch to be 1, so that Batch Apex will query for all Accounts that you want, but loop over them 1 at a time, so that you can do your query on each Account's contacts. To force the batch size to be 1, just pass in the batch size as an additional parameter:
No. It is not possible. If the logic is going to bring by 50,001 records it doesn't matter if you split it up into two queries one being 49,999 and the other bringing back 2. You still break the limit.