title: Android: performance cost of content provider queries within queries
body: <p>Writing this on the fly, so I apologize for the code sample. This is NOT real code, it's something I wrote in a plain text editor on the fly. No compile checking, couldn't remember all the exact class and method names, etc. It's just a written concept of what I'm trying to do, I'm looking for feedback on the broader concepts.</p>
  
  <p>I'm working on retrieving a list of contacts from the content provider. I want to be able to filter the results based on the contact's account name. the user will be presented with all available accounts, and will select which ones are to be used, and then that will be used in the retrieval method.</p>
  
  <p>The thing is, the account name is in RawContacts, and the rest of the info I want (display name, lookupID) is in Contacts. I know that ContactsContract.Contacts.Entity is the shortcut to access all of this, so this code sample is what I'm planning to do.</p>
  
  <p>Again, this is written on the fly with no IDE or looking up methods or anything. I'm sure my syntax is bad in many places, but this shows the concept I'm trying to do.</p>
  
  <pre><code>private static final URI URI = ContactsContract.Contacts.URI;
  private static final String[] FIRST_PROJECTION = new String[]{
      ContactsContract.Contacts.DISPLAY_NAME,
      ContactsContract.Contacts.LOOKUP_KEY
  };
  
  private String[] acceptedAccountNames = {Accepted Account Names Will Go Here (dynamic)};
  
  private static final String[] SECOND_PROJECTION = new String[]{
      ContactsContract.Contacts.Entity.ACCOUNT_NAME //This is whatever the entity -&gt; RawContacts field name would be
  };
  
  public List&lt;Contact&gt; loadContacts(Context context){
      List&lt;Contact&gt; contacts = new ArrayList&lt;&gt;();
      ContentProvider provider = context.getContentProvider();
      Cursor contactsCursor = provider.query(URI, FIRST_PROJECTION, null, null);
  
      contactsCursor.movetoFirst();
      while(!contactsCursor.isAtLast()){
          String name = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
          long lookupKey = contactsCursor.getLong(contactsCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
  
          Uri idUri = Uri.makeWithId(URI, lookupKey);
          Uri entityUri = Uri.makeWithTableName(idUri, "entity");
          Cursor contactEntityCursor = provider.query(entityUri, SECOND_PROJECTION, null, null);
  
          contactEntityCursor.moveToFirst();
          String accountName = contactEntityCursor.getString(contactEntityCursor.getColumnIndex(ContactsContract.Contacts.Entity.ACCOUNT_NAME));
  
          if(Arrays.asList(acceptedAccountNames).contains(accountName)){
              Contact contact = new Contact(lookupKey, name);
              contacts.add(contact);
          }
  
          contactsCursor.moveToNext();
      }
  
      return contacts;
  }
  </code></pre>
  
  <p>As you can see, I create a cursor while looping over another cursor. I'm essentially creating a new cursor for each contact in the list.</p>
  
  <p>My question is twofold:</p>
  
  <p>1) What would be the performance implications of this? With a large enough list, would this severely hurt app performance?</p>
  
  <p>2) Is there a better way to do this? As in, a way to do this in a single query, getting all the data I'm looking for in the cursor.</p>
  
  <p>Thanks so much in advance.</p>