обратная ссылка на движок приложения слишком медленная. Как я могу сделать это быстрее? - PullRequest
2 голосов
/ 12 мая 2010

Движок приложений Google имеет интеллектуальную функцию с именем обратных ссылок, и я обычно повторяю их там, где необходимо использовать вычисляемый столбец SQL.

Только представьте, что нужно накапливать определенную силу в л.с.

class Force(db.Model):
  hp = db.IntegerProperty()
class UnitGroup(db.Model):
  force = db.ReferenceProperty(reference_class=Force,collection_name="groups")
  hp = db.IntegerProperty()
class Unit(db.Model):
  group = db.ReferenceProperty(reference_class=UnitGroup,collection_name="units")
  hp = db.IntegerProperty()

Когда я кодировал, как следует, это было ужасно медленно (почти 3 с) с 20 силами с одной группой - одной единицей. (Я полагаю, обратная ссылка на принудительную перезагрузку суб-сущностей. Я права?)

def get_hp(self):
    hp = 0
    for group in self.groups:
        group_hp = 0
        for unit in group.units:
            group_hp += unit.hp
        hp += group_hp
    return hp

Как я могу оптимизировать этот код? Пожалуйста, учтите, что для каждой группы сил / юнитов должно быть рассчитано больше свойств, и я не хочу сохранять эти коллективные свойства для каждой сущности. :)

Ответы [ 2 ]

2 голосов
/ 12 мая 2010

Хранилище на App Engine дешево, а процессор и время запроса меньше. Главное, что вы должны помнить о хранилище данных, это то, что вы должны оптимизировать чтение, а не запись - в конечном итоге вы будете читать ваши данные гораздо чаще, чем пишете.

Если вы считаете, что вам когда-нибудь понадобится узнать общее количество Force hp, вам следует сохранить его в поле с именем total_hp и обновлять его новым значением при каждом обновлении / добавлении / удалении. его UnitGroup с и Unit с. Вероятно, вам следует сделать это и в транзакции, что означает, что они должны быть в одной группе объектов.

2 голосов
/ 12 мая 2010

Кажется, что Force, UnitGroup и Unit хорошо вписываются в Entity Group . Правда ли, что каждый юнит принадлежит одной и только одной группе юнитов и что каждая группа юнитов принадлежит одной и только одной силе? Если это так, то вы можете сохранить эти объекты как группу объектов и использовать запрос предка, чтобы уменьшить количество запросов к хранилищу данных.

Помещение сущностей в группу сущностей достигается установкой свойства parent при его создании. Как только это будет сделано, вы можете получить все Единицы, принадлежащие к силе, с помощью одного запроса предка .

Как говорится, правильная вещь, которую нужно сделать , - это вычислять значения при записи сущностей в базу данных, а не при их чтении. Этот простой факт неоднократно отмечался здесь и в других местах, и это лучший способ получить хорошую производительность от вашего приложения AppEngine. Это может показаться большой работой заранее, и это очень нелогично для тех, кто имеет опыт работы с традиционными базами данных SQL, но это то, что вы хотите сделать, просто и ясно.

...