List<Account> accountList = [SELECT Id 
                              FROM Account 
                              WHERE BillingCity='Pune'];

 List<Id> accountIds = new List<Id>();

 for(account accountRecord : accountList){
 /* Line 1 */
 List<Opportunity> opportunityList1 = [SELECT Id, Amount 
                                       FROM Opportunity 
                                       WHERE accountId IN: accountIds];

 /* Line 2 */
 List<Opportunity> opportunityList2 = [SELECT Id, Amount 
                                       FROM Opportunity 
                                       WHERE accountId IN:accountList ];

Are the line both line are the same ? If any difference, what are the difference(s)?

Any limitation in the above query ?

3 Answers 3


It's probably a wash.

If your number of parents is very large (~49k records), using Set<Id> is marginally (~16%) faster. For me, the List<SObject> merge query took on average .208s and the Set<Id> merge query took on average .179s. That does affect the number of queries you could run in a transaction, but for a single query doesn't save you much.

If the number of parents is small, it seems like List<SObject> may actually be faster, clocking in at 3.5ms, as opposed to Set<Id> at 4.1ms for a differential of 17%.

I timed the query as demonstrated below, swapping 100 for 49000 and parents for parentIds as needed to generate the above data. I ran 5 trials with each configuration so the sample size is not huge.

List<Account> parents = [SELECT Id FROM Account LIMIT 49000];
Set<Id> parentIds = Pluck.ids(parents);

Long start = Datetime.now().getTime();
for (Integer i = 1; i < 10; i++)
    List<Opportunity> records = [SELECT Id FROM Opportunity WHERE AccountId = :parentIds];
system.debug(Datetime.now().getTime() - start);

My child table was pretty empty, you could probably rerun this analysis with a heavily used child table and get completely different results.


There is no difference in both statement except using an extra variable.

If you need only Account id for other purpose then store the Account Ids in list/set for further use.

if you don't need then I suggest 2nd option is optimal one

Direct query with list of sobject.

 List<Opportunity> opportunityList2 = [SELECT Id, Amount 
                                       FROM Opportunity 
                                       WHERE accountId IN: accountList ];

The second line will give you a following error,

COMPILE ERROR: Invalid bind expression type of Account for Id field of SObject Opportunity

In second line, compiler expects to have Id type for binding where as you have given the list type for binding.

  • 4
    Run exactly the code posted in execute anonymous and you will find that the error you have posted does not occur.
    – Keith C
    Commented Jul 12, 2016 at 7:57
  • Could someone please explain why does it work, intuitively I would have said that it would generate an error. Commented Jul 12, 2016 at 13:46
  • If we pass list it works fine. Opportunity Query will fetch exactly id from the parentList. Commented Jul 13, 2016 at 5:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .