As we know, Apex runs in a multitenant environment so to restrict the runaway apex code/processes to acquire shared resources, the Apex runtime engine strictly enforces these governor limits. These governor limits count for each Apex transaction. For each execution of a batch, these limits are reset in its execute method. Some of these Limits are different for synchronous Apex and asynchronous Apex (Batch Apex and future methods).
The total number of records retrieved by SOQL queries for synchronous Apex and asynchronous Apex is 50000. This is the per-transaction limit, and not a per-query limit. You can request Salesforce to increase your query rows governor limit to 100,000 rows for your Org.
How to prevent this error:
- SOQL calls should be filtered. They should have a WHERE clause and LIMIT which could prevent this exception.
- Check rows returning from all SOQL queries in the transaction, not in a single SOQL query.
- Use these debug statements to check query rows governor limit of your org and the rows queried so far in your code-
System.debug(‘Total number of records retrieved by SOQL queries:’+Limits.getLimitDmlRows());
System.debug(‘Number of records retrieved by SOQL queries so far: ‘ + Limits.getDmlRows());
- One most important thing that everyone misses out on is Aggregate queries thinking, it is returning only the aggregate rows but queries with aggregate functions count each row used by the aggregation(as a query row) for limit tracking.