2

I am new to using custom metadata types. From what I have read so far, it looks like i can make unlimited number of queries to a custom metadata type in an apex transaction.

Would that mean that it is ok to query a Custom metadata type in a for loop? If yes - is that a good practice?

3

As Salesfoce follows a multi-tenant architecture, that necessarily implies you cannot make unlimited number of queries (even though you can for custom metadata types per documentation) or use any unlimited resources. Note that there are still some rules governing the SOQL usage for custom metadata type, e.g., the below excerpt from documentation:

SOQL queries containing long text area fields Count toward Apex governor limits.

And this is the primary reason why you should not use SOQL within for loops is to avoid governor limits. This holds true irrespective of what you are querying for. Here's the motivation for advice why you should not write SOQL inside loops (refer to this link for details).

By moving queries outside of for loops, your code will run faster, and is less likely to exceed governor limits. A common mistake is that queries are placed inside a for loop. There is a governor limit that enforces a maximum number of SOQL queries. When queries are placed inside a for loop, a query is executed on each iteration and governor limit is easily reached. Instead, move the SOQL query outside of the for loop and retrieve all the necessary data in a single query.

As for your question -- You should not (at least try not to) have queries within loops and try to utilize the best practices which ultimately yields better performance for your application.

5

The documentation states that you do get unlimited queries, but you're still limited by query rows. As such, you should attempt to optimize your code to use as few queries as possible.

For example, here's the output from one of our metadata tables that has 1,224 rows, when we query it once:

21:20:52.1 (241740102)|USER_DEBUG|[3]|DEBUG|Limits.getQueryRows: 1224
21:20:52.1 (241758076)|USER_DEBUG|[4]|DEBUG|Limits.getQueries: 0

And here's the output from doing 40 queries:

21:23:18.1 (468898239)|USER_DEBUG|[3]|DEBUG|Limits.getQueryRows: 48960
21:23:18.1 (468917235)|USER_DEBUG|[4]|DEBUG|Limits.getQueries: 0

And 41 queries:

21:23:47.1 (527992170)|EXCEPTION_THROWN|[2]|System.LimitException: Too many query rows: 50001
21:23:47.1 (528427073)|FATAL_ERROR|System.LimitException: Too many query rows: 50001

So, while you do get an "unlimited" number of queries to custom metadata, keep in mind that you are still using CPU time, heap limits, and row limits. Query only what you need to, and cache your results for performance reasons.

In practice, this limit means you couldn't actually get away with querying custom metadata more than 50,000 times at one row a piece.

Also, based on testing, there's some CPU time used for each query, so the net result is that you'll eventually hit CPU time limits. In my test, hitting my 1,224 entry table in a loop resulted in a CPU time usage of about 5.5 ms per query. This may seem like a small value, but multiply that by 1,000 and you're already at 5.5 seconds of CPU time just to process those records.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.