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
rtyanasrtyanas 

Increase - Number of SOQL queries: 101 out of 100

I would like to increase the number of queries I have available.  The solution I have which goes over the limit I feel is elegent and works and is done! 

 

I feel like this limit on queries is limiting the developer to code to lower standards.

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

You can use two child queries, with a caveat that they have to be distinct relationships (e.g. they must use separate lookup fields).

 

For example, you can do this:

 

SELECT Api_Name__c,
(SELECT a_name__c,data__c,mandatory__c,description__c from Rq_Descriptions__r),
(SELECT a_name__c,data__c,description__c from Rs_Descriptions__r)
FROM Api_Document__c

Access to those child lists is given through the relationship name (e.g. Rq_Descriptions__r and Rs_Descriptions__r).

 

Your code can then appear as:

 

        <apex:pageBlockTable  value="{!apiD.Rq_Descriptions__r}" var="rq" >
           <apex:column value="{!rq.A_Name__c}" />
           <apex:column value="{!rq.Data__c}" />
           <apex:column value="{!rq.Mandatory__c}" />
           <apex:column value="{!rq.Description__c}" />
        </apex:pageBlockTable>
            
         <apex:pageBlockTable value="{!apiD.Rs_Descriptions__r}" var="rs" >
           <apex:column value="{!rs.A_Name__c}" />
           <apex:column value="{!rs.Data__c}" headerclass="headertitle"/>
           <apex:column value="{!rs.Description__c}" />
         </apex:pageBlockTable>

 

All Answers

vishal@forcevishal@force

Posting such "REQUESTS" here won't help. This forum is meant for Developers to learn how to optimize their code to ensure they stay within the SFDC limits. If you post your code, someone might be able to give you a better solution that won't hit the SOQL Query limitation. 

 

Cheers!

rtyanasrtyanas
 public class API_DocumentRqAndRs {
        public API_Document__c apiDoc{get; set;}
        public List<Rq_Argument_Description__c> rqArgList{get; set;}
        public List<Rs_Argument_Description__c> rsArgList{get; set;}
    }

    public List<API_DocumentRqAndRs> getApiDocumentListRqAndRs(){
        List<API_DocumentRqAndRs> apiDocRqRsList = new List<API_DocumentRqAndRs>() ;
        // Build master list using this list
        List<API_Document__c> apiList = getApiDocumentList();  
        
        API_DocumentRqAndRs apiDocRqRs;
        for(API_Document__c apiDoc : apiList) {
            apiDocRqRs = new API_DocumentReqAndResp();
            apiDocRqRs.apiDoc = apiDoc;
            // Sets the key to query on
	    fApiController.setapiDocId(apiDoc.id);             
            // This returns a query
    	    apiDocRqRs.rqArgList  = fApiController.getRqArg(); 
            // This returns a query
            apiDocRqRs.rsArgList  = fApiController.getRsArg(); 
            apiDocRqRsList.add(apiDocReqResp);
        }
        
        return apiDocRqRsList;
    }

 

I query for a list from the documents then using that list I create another list of documents with child records.  Right now I cannot hink of another way to do this since I need all the child records for each document.  For every document I have to have the related child records.  Then I display all this to the user.

 

The records will have to be queried eventually to match the parent.  Why would I need a DB if I was going to read all the child records into a flat file and match the records on my own?  Why do I need a DB when I cannot make queries??

 

Help please!

sfdcfoxsfdcfox

rtyanas,

 

The limits are in place so that all code has an equal chance to run without overloading hardware capacity. You say that a system that uses more queries is somehow better and conforms to higher standards than one that uses fewer queries. In fact, the opposite is true. I shall prove this with a simple piece of code:

 

for(Lead record:[SELECT Id,FistName,LastName FROM Lead WHERE Id IN :Trigger.new]) {
  Task[] tasks = [SELECT Id,Subject FROM Task WHERE WhoId = :record.Id];
  for(Task leadTask:tasks) {
    if(leadTask.Subject=='Test') {
      delete leadTask;
    }
  }
}

This code uses at minimum two queries, and one query for each additional lead beyond the first in the trigger. It also performs slow DML by operating only on one record at a time, and it also queries records that will not eventually be modified, increasing the number of rows returned unnecessarily. This code could also easily run upwards of hundreds of thousands of script statements on leads with many tasks.

 

 Here is how an expert would write this:

 

delete [SELECT Id FROM Task WHERE Subject='Test' AND WhoId IN :Trigger.new];

This code uses only 1 query, regardless of the number of leads or tasks, and performs exactly 1 DML statement, regardless of the number of tasks to be deleted (the system will automatically break them into chunks of 200 records per delete). It requires just 1 script line of execution, and no heap memory. It queries only records that meet the specific criteria without any extra waste.

 

By your logic, you are saying that the first version of the code I wrote here as an example is somehow more efficient, more elegant, and of higher standards and quality than the latter. This is clearly not the case, as the former example is slow, bloated, does not scale well, and will consume many resources. You may feel that your code is very well written, and "done," but it is not efficient enough to use on this platform. Your code must share resources with other applications, and it is your responsibility to make sure that your application follows these rules.

 

Fewer queries leads to higher code quality and faster execution time. Until you understand this, you will never appreciate what it means to be a salesforce.com developer (or any other type of developer). No competent developer will state that they cannot work within the limits of the system and need more resources. They will instead find inventive solutions that work within the parameters of the system. This is the difference between a developer that wants lots of money and a developer that wants to write great code (which in turn will actually yield lots of money).

 

Nobody will want to use your "elegant" system which takes 10+ seconds between each page, which is what will happen if you're continually bumping up against the 100 query limit.

sfdcfoxsfdcfox
Nobody said you can't use a query; in fact, you could use a subquery to return the documents with their associated child records using just a single line of code. You abstracted your queries into a class, and that class is inefficient. Instead, apiList should be sent to a class that runs a query against all records in the list and returns the results back to your controller.

Your problem is that you are abstracting where you shouldn't be, which is inefficient. It's okay to have wrapper classes if you must, but you need to know when to use them, and when to just use primitive SObject objects.

And as far as "reading the child records into a flat file", you clearly don't understand the point of this database. It is a relational database. It anchors together all of your data. A flat file couldn't offer you that convenience, nor could you use out of the box record-based and field-based security mechanisms, and so on.
rtyanasrtyanas

 

A DB works when I can use it, if I could have used one query I would have.  I would like to make it easier by not making it easier for salesforce.

 

With this requirement I created a query with one child record but, I need to access 2 child records for each document.

 

SELECT API_Name__c,
(
    Select a_name__c from  Rq_Descriptions__r
)
FROM API_Document__c

This query works for one child table my scenario I have 2 child tables, I could not find an example of this so I moved to using the list method which did work fine until I had an increase number of records.  ( Number of SOQL queries: 101 out of 100)

 

If I could have gotten the parent with (2) child query to work, I do not know how I would have displayed this on VisualForce, I am using repeat to make this happen now.


           

  <apex:repeat value="{!ApiDocumentListRqAndRs}" var="apiD" >

     <apex:outputField value="{!apiD.apiDoc.Description__c}" /> 
     <pre class="alignleft">{!apiD.apiDoc.Rq_Format__c}</pre>

...
<!-- These are the children -->
        <apex:pageBlockTable  value="{!apiD.rqList}" var="rq" >
           <apex:column value="{!rq.A_Name__c}" />
           <apex:column value="{!rq.Data__c}" />
           <apex:column value="{!rq.Mandatory__c}" />
           <apex:column value="{!rq.Description__c}" />
        </apex:pageBlockTable>
            
         <apex:pageBlockTable value="{!apiD.rsList}" var="rs" >
           <apex:column value="{!rs.A_Name__c}" />
           <apex:column value="{!rs.Data__c}" headerclass="headertitle"/>
           <apex:column value="{!rs.Description__c}" />
         </apex:pageBlockTable>
...

 

The BlockTable is working fine with the list I populate using the for loop.  But ( Number of SOQL queries: 101 out of 100) limitations are keeping me from moving forward.

 

Please help.  Any ideas on a query with one parent and 2 children?  Any ideas on displaying this structure in VisualForce?

 

Thanks.

sfdcfoxsfdcfox

You can use two child queries, with a caveat that they have to be distinct relationships (e.g. they must use separate lookup fields).

 

For example, you can do this:

 

SELECT Api_Name__c,
(SELECT a_name__c,data__c,mandatory__c,description__c from Rq_Descriptions__r),
(SELECT a_name__c,data__c,description__c from Rs_Descriptions__r)
FROM Api_Document__c

Access to those child lists is given through the relationship name (e.g. Rq_Descriptions__r and Rs_Descriptions__r).

 

Your code can then appear as:

 

        <apex:pageBlockTable  value="{!apiD.Rq_Descriptions__r}" var="rq" >
           <apex:column value="{!rq.A_Name__c}" />
           <apex:column value="{!rq.Data__c}" />
           <apex:column value="{!rq.Mandatory__c}" />
           <apex:column value="{!rq.Description__c}" />
        </apex:pageBlockTable>
            
         <apex:pageBlockTable value="{!apiD.Rs_Descriptions__r}" var="rs" >
           <apex:column value="{!rs.A_Name__c}" />
           <apex:column value="{!rs.Data__c}" headerclass="headertitle"/>
           <apex:column value="{!rs.Description__c}" />
         </apex:pageBlockTable>

 

This was selected as the best answer
rtyanasrtyanas

 

Thanks sandwich person I'm down to 5 queries with same output.