Сколько операций чтения из Datastore потребляет каждая операция Fetch, Count и Query?

Я читаю в группах Google App Engine многих пользователей ( рис. 1, рис. 2, рис. 3), которые не могут понять, откуда поступает большое количество операций чтения из Datastore в их отчетах о выставлении счетов.
Как вы, возможно, знаете, количество операций чтения из хранилища данных ограничено до 50 тыс. Операций в день, сверх этого бюджета вы должны заплатить.

Операции 50K звучат как много ресурсов, но, к несчастью, кажется, что каждая операция (Query, Entity fetch, Count..) скрывает несколько операций чтения из Datastore.

Можно ли узнать через API или другой подход, сколько операций чтения из Datastore скрыто за общим RPC.get, RPC.runquery звонки?

Appstats в этом случае кажется бесполезным, потому что он дает только детали RPC, а не стоимость скрытого чтения.

Имея простую модель, подобную этой:

class Example(db.Model):
    foo = db.StringProperty()    
    bars= db.ListProperty(str)

и 1000 сущностей в хранилище данных, меня интересует стоимость такого рода операций:

items_count =  Example.all(keys_only = True).filter('bars=','spam').count()

items_count = Example.all().count(10000) 

items = Example.all().fetch(10000)

items = Example.all().filter('bars=','spam').filter('bars=','fu').fetch(10000)

items = Example.all().fetch(10000, offset=500)

items = Example.all().filter('foo>=', filtr).filter('foo<', filtr+ u'\ufffd')

2 ответа

Решение

См. http://code.google.com/appengine/docs/billing.html. Запрос стоит 1 чтение плюс 1 чтение для каждой возвращенной сущности. "Возвращено" включает объекты, пропущенные по смещению или количеству. Таким образом, 1001 читает для каждого из них:

Example.all(keys_only = True).filter('bars=','spam').count() 
Example.all().count(1000)
Example.all().fetch(1000)
Example.all().fetch(1000, offset=500)

Для них количество начисленных чтений равно 1 плюс количество объектов, которые соответствуют фильтрам:

Example.all().filter('bars=','spam').filter('bars=','fu').fetch()
Example.all().filter('foo>=', filtr).filter('foo<', filtr+ u'\ufffd').fetch()

Вместо того, чтобы использовать счетчик, вам следует рассмотреть возможность сохранения счетчика в хранилище данных, если вам нужно обновлять счетчик чаще, чем раз в секунду. http://code.google.com/appengine/articles/sharding_counters.html

По возможности вы должны использовать курсоры вместо смещения.

Просто чтобы убедиться:

Я почти уверен

Example.all().count(10000)

В этом случае используются небольшие операции с хранилищем данных (не нужно извлекать сущности, только ключи), поэтому это будет считаться как 1 чтение + 10 000 (макс.) Мелких операций.

Другие вопросы по тегам