Чрезмерные операции с небольшим хранилищем данных в приложении Google

У меня возникли проблемы с хранилищем данных Google. С тех пор, как была введена новая модель ценообразования, стоимость запуска моего приложения значительно увеличилась.

Преступник, похоже, "мелкие операции с хранилищем данных", которые поступают на более чем 20 миллионов операций в день!

У кого-нибудь была эта проблема, я не думаю, что я делаю чрезмерное количество ключевых поисков, и у меня только 5000 пользователей, с примерно 10-20 запросами в минуту.

Спасибо заранее!

Edit

Хорошо получилась статистика, после 3 часов. Вот что я вижу на панели инструментов в разделе биллинга: Appengine dashboard - billing

И вот некоторые из характеристик:

Stats

Очевидно, что в datastore.get довольно много вызовов. Я начинаю думать, что это мой дизайн, который вызывает проблему. Они соответствуют счетам. У каждого пользователя есть учетная запись, но учетная запись может быть одного из двух типов, для этого я использую композицию. Таким образом, каждый объект учетной записи имеет ссылку на свою дочернюю учетную запись. В результате, когда я выполняю поиск ближайших пользователей, он включает выборку учетных записей с использованием запроса и последующее получение каждой учетной записи, чтобы получить ее вспомогательную учетную запись. Верхний запрос в картине статистики - это вызов, который получает 100 учетных записей, а затем должен получить доступ к каждому из них. Я бы подумал, что это очень легкий запрос, но я думаю, нет. И я все еще смущен количеством записываемых данных на моем приборном щитке.

Ответ 1

Определенно использовать appstats, как предлагает Дрю; независимо от того, какую библиотеку вы используете, он расскажет вам, какие операции выполняются обработчиками. Наиболее вероятными виновниками являются запросы только на ключи и операции подсчета.

Ответ 2

Мой совет: использовать AppStats (Python/Java), чтобы профилировать ваш трафик и выяснить, какой обработчик генерирует большинство операций хранилища данных. Если вы разместите здесь код, мы можем предложить оптимизацию.

Ответ 3

Не сканируйте свой хранилище данных, используйте get (ключ) или get_by_id (id) или get_by_key_name (имя ключа) столько, сколько сможете.

Ответ 4

У вас есть много свойств ReferenceProperty в ваших моделях? Доступ к ним приведет к вызову db.get для каждого свойства, если вы их не предварительно выберете. Это вызовет запросы 101 db.get.

class Foo(db.Model):
   user = db.ReferenceProperty(User)

foos = Foo.all().fetch(100)
for f in foos:
  print f.user.name  # this triggers db.get(parent=f, key=f.user)