2013-02-13 7 views
3

Я ищу совета, как я могу улучшить это с точки зрения скорости:улучшить ОПРС производительность запросов

Мои данные-модель:

class Events(ndb.Model): 
    eventid = ndb.StringProperty(required=True) 
    participants = ndb.StringProperty(repeated=True) 

Так я пытаюсь получить данные:

def GetEventDataNotCached(eventslist): 
    futures = [] 
    for eventid in eventslist: 
     if eventid is not None: 
      ke = database.Events.query(database.Events.eventid == eventid) 
      future = ke.get_async(keys_only = True) 
      futures.append(future) 

    eventskeys = [] 
    for future in futures: 
     eventkey = future.get_result() 
     eventskeys.append(eventkey) 

    data = ndb.get_multi(eventskeys) 

Таким образом, я получаю ключи асинхронизации и передаю ключи к «get_multi» - есть ли способ сделать это быстрее, поскольку я все еще не счастлив пока что с производительностью.

В повторном имуществе может быть до нескольких сотен строк. В модели Events есть несколько 10.000 строк. В списке событий всего несколько десятков мероприятий, которые я хочу получить.

+0

Я не уверен, что это сделает работу лучше или хуже, но, возможно, вы можете создать объект Участники. Particpants.query (eventid в списке событий) –

ответ

2

Улучшение в простоте и скорости выполнения, но не стоимость может быть:

data = database.Events.query(database.Events.eventid.IN(eventslist)).fetch(100) 

Следующий шаг должен иметь EventID как идентификатор ключа, созданный как

event = Event(id=eventid, ...) 

в этом случае вы делаете

data = ndb. get_multi(ndb.Key(Event, eventid) for eventid in eventlist) 

Который быстрее и длиннее (список событий) * в 6 раз дешевле.

5

Я обнаружил, что служебные данные десериализации из протокольного буфера длинных списков (т. Е. Большие repeated=True) очень бедны.

Вы посмотрели на это в appstats? Вы видите большой пробел в пробеле, где RPC не выполняется после вашего get_multi()? Это накладные расходы десериализации.

Единственный способ, с помощью которого я смог преодолеть это, - удалить длинные списки и управлять ими в отдельной модели (т. Е. Избегать длинного повторного списка свойств вообще), но, конечно, это может быть невозможно для вашего использование случай.

Итак, большой вопрос: вам действительно нужны все участники, когда вы получаете список событий, или можете отложить этот поиск каким-то образом? Например, может быть дешевле/быстрее получать все события синхронно, а затем удалять асинхронные выборки для участников для каждого события (из другой модели) и объединять в памяти - возможно, вам нужны только 25 последних зарегистрированных участников или что-то еще, таким образом, можно ограничить стоимость ваших подзапросов?

Смежные вопросы