Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are keys-only queries free?

According to pricing docs here, a keys-only query is free. So it seems you can save a read by doing the following (pseudo-code):

qo = ndb.QueryOptions(keys_only = True)
qry = ModelName.query().filter("name" = "Bob")
keys = qry.fetch(20, options = qo) #keys-only fetch

Then afterward I can get my entities, costing 1 read per entity:

entities = ndb.get_multi(keys)

Why is this considered better than fetching the entities (i.e. doing a keys-only fetch)?

Also, where does the query charge come from? When the fetch is performed or when the query object is created?

like image 589
user3058197 Avatar asked Mar 20 '23 01:03

user3058197


1 Answers

This isn't considered "better", you just save yourself 1 extra read cost per query. This comes at the cost of an extra RPC request with billable instance time.

When you do a normal query (i.e. a non keys-only query) you are returned the objects you are looking for. The RPC request that runs the query will also start to fetch each object the query matches and thus you can get all your results faster. Depending on the result size of the query, it can all be fetched in a single RPC request (you can adjust batch_size to adjust the total amount of RPCs a query takes).

The way the query works is by a single RPC request scanning your indexes for all keys that match your query and if its a keys only query, it returns just the resulting list. If its a normal query, it will start to grab the objects you want and perform additional RPC requests to get them all as needed.

The charge comes when the query is executed, so in your example, when fetch is called. You are just building up the query and its filters beforehand.

There is an advantage to doing it your way though: The fetched objects can always be assumed to be consistent. That is, with a query your result is not guaranteed to be "consistent" with any updates that may have just occurred. Both methods will suffer from eventual consistency in that the objects that match your query might not all be read consistently from the indexes unless you do an ancestor query, but your method can guarantee that the objects you fetch by using their keys are indeed the most up-to-date versions.

like image 170
someone1 Avatar answered Mar 24 '23 22:03

someone1