Scenario 1:
User A: Has 2500 pending tasks. The query limit is 500 and results fetched on the first request are obviously 500. Time taken: 5767 milliseconds (5.7 seconds).
User B: Has 2 pending tasks. The query limit is 500 and results fetched on the first request are obviously 2. Time taken: 7124 milliseconds (7.1 seconds).
Scenario 2:
User A: Has 2500 pending tasks. The query limit is 10 and results fetched on the first request are obviously 10. Time taken: ~400 milliseconds (1/2 second).
User B: Has 2 pending tasks. The query limit is 10 and results fetched on the first request are obviously 2. Time taken: 5-6 seconds.
Scenario 3:
User A: Has 2500 pending tasks. The query limit is 551 and results fetched on the first request are obviously 551. Time taken: 6251 milliseconds (6 seconds).
User B: Has 551 pending tasks. The query limit is 551 and results fetched on the first request are obviously 551. Time taken: 13053 milliseconds (13 seconds).
I can't find a pattern here. How do I optimize my queries so that users with less data can get their pages loaded quickly.
public static Map <String , Object> getEntitiesUsingQueryCursor( String kind , int limit , int chunkSize , String currentCursor, String account, String user, Boolean status, String dept ) throws Exception
{
String nextCursor = null;
Entity entity = null;
List <Entity> listOfEntity = new ArrayList <Entity>();
Map <String , Object> result = new HashMap <String , Object>();
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
com.google.appengine.api.datastore.Query q = new com.google.appengine.api.datastore.Query( kind );
List <Filter> listOfFilter = new ArrayList <Filter>();
Filter filter1 = new FilterPredicate( "accountID" , FilterOperator.EQUAL , account);
Filter filter2 = new FilterPredicate( "assigneeID" , FilterOperator.EQUAL , user);
Filter filter3 = new FilterPredicate( "departmentID" , FilterOperator.EQUAL , dept);
Filter filter4 = new FilterPredicate( "open" , FilterOperator.EQUAL , status); //Boolean
listOfFilter.add( filter1 );
listOfFilter.add( filter2 );
listOfFilter.add( filter3 );
listOfFilter.add( filter4 );
Filter filterParams1 = filterParams = CompositeFilterOperator.and( listOfFilter );
q.setFilter( filter );
PreparedQuery pq = datastore.prepare( q );
FetchOptions fetchOptions = FetchOptions.Builder.withLimit(limit).prefetchSize( chunkSize ).chunkSize( chunkSize );// limit & chunksize - 500
if ( !StringUtil.isBlank( currentCursor ) )
fetchOptions.startCursor( Cursor.fromWebSafeString( currentCursor ) );
QueryResultIterable <Entity> results = pq.asQueryResultIterable( fetchOptions );
QueryResultIterator <Entity> iterator = results.iterator();
while ( iterator.hasNext() )
{
entity = iterator.next();
listOfEntity.add( entity );
}
if(listOfEntity.size() == limit)
nextCursor = iterator.getCursor().toWebSafeString();
result.put( "cursor" , nextCursor );
result.put( "entity" , listOfEntity );
return result;
}