I have a Google App Engine java application, which performs well for my needs, but I'd like to optimize for datastore operation costs.
I understand that small datastore operations are free, and from the same article that key-only queries use small operations...
Small datastore operations include calls to allocate datastore ids or keys-only queries
... so I expected that if I do a key-only query, and use the key from the first retrieved 'entity' to get the full entity then it should cost me 1 small operation, plus one (large) read operation in total - only the latter of which costs money. This is exactly the same logic used in this Stack Overflow question. If I ran the same thing by just doing a regular query and fetching the first entity, it would cost me 1 + 1 (large) read.
But... when I run appstats on my application, what I see is that the query costs me 1 Read, plus 1 small, and then I also have to pay for the get:
@15ms datastore_v3.RunQuery real=8ms api=0ms cost=80 billed_ops=[DATASTORE_READ:1, DATASTORE_SMALL:1]
@6ms datastore_v3.Get real=7ms api=0ms cost=70 billed_ops=[DATASTORE_READ:1]
... so this is costing me 1 more read than I expected, and 1 extra small operation compared with what I was doing before.
Example bit of java code looks like this:
Query query = new Query(<Entity Name>).setKeysOnly();
Filter filter = new FilterPredicate(<Field Name>, Query.FilterOperator.EQUAL, <Some Value>);
query.setFilter(filter);
List<Entity> resultsSet = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(<Max Rows>));
Entity entity = datastore.get(resultsSet.get(0).getKey());
Question is: am I implementing this wrong, or did I just misunderstand how the pricing works? Thanks.
datastore.prepare(query).asList(FetchOptions.Builder.withLimit(<Max Rows>)).get(0).getKey(), the second isdatastore.get(key);. - konqi