Сколько операций чтения из 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 (макс.) Мелких операций.