I've just started getting the following error on my server. This query
had been working fine for months, and I haven't changed the indexes
lately. Are there some indexes that just buckle under heavy load or
larger data sets? This particular table contains only 242,604 entries.
The built-in indices are not efficient enough for this query and
your data. Please add a composite index for this query.. An index is
missing but we are unable to tell you which one due to a bug in the
App Engine SDK. If your query only contains equality filters you most
likely need a composite index on all the properties referenced in
those filters.
(full stack dump included below)
My query source code:
Query query = pm.newQuery(GameDataV2.class);
Object[] params;
query.declareParameters(
"com.google.appengine.api.datastore.Key userKeyParam"
+ ", com.honkentuber.wordwise.GameState stateParam1"
+ ", com.honkentuber.wordwise.GameState stateParam2"
+ ", com.honkentuber.wordwise.GameState stateParam3");
params = new Object[4];
params[0] = userKey;
params[1] = GameState.PENDING;
params[2] = GameState.PLAYER_TURN;
params[3] = GameState.OPPONENT_TURN;
query.setFilter("(memberKeys == userKeyParam)"
+ " && ((state == stateParam1)"
+ " || (state == stateParam2)"
+ " || (state == stateParam3))");
List<GameDataV2> gamesData = (List<GameDataV2>)
query.executeWithArray(params);
I have the following 2 indexes defined:
memberKeys ▲ , state ▲ , memberLastAccessMs ▲
memberKeys ▲ , state ▲ , memberScores ▼
I'm not sure why I don't have an index with only memberKeys and state
- does datastore-indexes autoGenerate not generate a new index if it
already has a superset index?
I've changed the query to the following in my local development
environment:
Query query = pm.newQuery(GameDataV2.class);
query.setFilter("(memberKeys == :userKeyParam)
&& :statesParam.contains(state)");
List<GameDataV2> gamesData = (List<GameDataV2>) query.execute(
userKey,
Arrays.asList(
GameState.PENDING.name(),
GameState.PLAYER_TURN.name(),
GameState.OPPONENT_TURN.name()));
Some questions about this:
1) Running locally with autoGenerate="true", I'm not getting a new
GameDataV2 index on memberKeys and states. Does contains() not require
an index on that field? Is this just generating 2 separate queries
internally?
2) Is the contains() query more efficient than the nested ORs I had in
my original query? Or will I still get the "not efficient enough for
this query and your data" error?
3) Why do enumerated types not work with contains()? I had to
add .name() to each entry in the list to get this to work.
4) Why do declared parameters not work with collections? I tried
declaring statesParam as a both List<GameState> and List, and I got
errors resolving the types.
com.google.appengine.api.datastore.DatastoreNeedIndexException: The
built-in indices are not efficient enough for this query and your
data. Please add a composite index for this query.. An index is
missing but we are unable to tell you which one due to a bug in the
App Engine SDK. If your query only contains equality filters you most
likely need a composite index on all the properties referenced in
those filters.
at
com.google.appengine.api.datastore.DatastoreApiHelper.translateError(DatastoreApiHelper.java:
40)
at
com.google.appengine.api.datastore.DatastoreApiHelper.makeSyncCall(DatastoreApiHelper.java:
67)
at
com.google.appengine.api.datastore.PreparedQueryImpl.runQuery(PreparedQueryImpl.java:
127)
at
com.google.appengine.api.datastore.PreparedQueryImpl.asIterator(PreparedQueryImpl.java:
87)
at com.google.appengine.api.datastore.PreparedMultiQuery
$DedupingMultiQueryIterator.getNextIterator(PreparedMultiQuery.java:
154)
at com.google.appengine.api.datastore.PreparedMultiQuery
$DedupingMultiQueryIterator.computeNext(PreparedMultiQuery.java:173)
at com.google.appengine.api.datastore.PreparedMultiQuery
$DedupingMultiQueryIterator.computeNext(PreparedMultiQuery.java:98)
at
com.google.appengine.api.datastore.AbstractIterator.tryToComputeNext(AbstractIterator.java:
52)
at
com.google.appengine.api.datastore.AbstractIterator.hasNext(AbstractIterator.java:
47)
at com.google.appengine.api.datastore.BasePreparedQuery
$UncompilablePreparedQuery$1.hasNext(BasePreparedQuery.java:78)
at
org.datanucleus.store.appengine.query.RuntimeExceptionWrappingIterator.hasNext(RuntimeExceptionWrappingIterator.java:
44)
at
org.datanucleus.store.appengine.query.LazyResult.resolveAll(LazyResult.java:
115)
at
org.datanucleus.store.appengine.query.LazyResult.size(LazyResult.java:
110)
at
org.datanucleus.store.appengine.query.StreamingQueryResult.size(StreamingQueryResult.java:
124)
at
org.datanucleus.store.query.AbstractQueryResult.toArray(AbstractQueryResult.java:
399)
at java.util.ArrayList.addAll(Unknown Source)
--
You received this message because you are subscribed to the Google Groups
"Google App Engine for Java" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-appengine-java?hl=en.