Запрашивая те же поля для различных значений на AppEngine


Я создаю журнал. Многие студенты получают ранг во многих стандартах каждого. Я надеялся получить помощь для анализа кода для эффективного использования асинхронных результат выборки. ofy - это объективировать объект, который является в основном просто удобство оболочкой асинхронные получение возможности AppEngine.

public List<StandardScoreDAO> getStandardScores(
        ArrayList<Long> studentIdLongs, ArrayList<Long> standardIdLongs)
{
    ObjectifyService.register(StandardScoreDAO.class);
    Objectify ofy = ObjectifyService.begin();

    List<Iterator<StandardScoreDAO>> results = new ArrayList<Iterator<StandardScoreDAO>>();

    for (Long studentId : studentIdLongs)
    {
        for (Long standardId : standardIdLongs)
        {
            results.add(ofy.query(StandardScoreDAO.class)
                    .filter("measuredUserId =", studentId)
                    .filter("standardId =", standardId)
                    .iterator());
        }
    }

    ArrayList<StandardScoreDAO> ret = new ArrayList<StandardScoreDAO>();

    for (Iterator<StandardScoreDAO> i : results)
    {
        while (i.hasNext())
        {
            ret.add(i.next());
        }
    }

    return ret;
}

Как вы можете видеть, если есть 100 studentIds и 100 standardIds, это 10 000 запросов. AppEngine будет работать только 10 параллельно. Aiee! Я не знаю, если это вообще реально ожидать этого, чтобы закончить за 30 секунд (только тестирование), но я интересно, если кто-нибудь увидит гораздо лучший способ организовать это.



1882
2
задан 31 марта 2011 в 01:03 Источник Поделиться
Комментарии
1 ответ

С объективировать, у вас есть возможность использовать оператор "in" в запросе. Кроме того, станет ясно из второго блока вложенные циклы, которые вы только ищете пересечение двух наборов measuredUserIds и standardIds. Так, один оператор следует сделать трюк:

public List<StandardScoreDAO> getStandardScores(
ArrayList<Long> studentIdLongs, ArrayList<Long> standardIdLongs) {
ObjectifyService.register(StandardScoreDAO.class);
Objectify ofy = ObjectifyService.begin();

Iterator<StandardScoreDAO> i = ofy.query(StandardScoreDAO.class)
.filter("measuredUserId in", studentIdLongs)
.filter("standardId in", standardIdLongs)
.iterator();

List<StandardScoreDAO> ret = new LinkedList<StandardScoreDAO>();

while (i.hasNext()) {
ret.add(i.next());
}

return ret;
}

Если открыть список только на повторе (а не произвольного доступа или по индексу), и не знаете его размер при создании, LinkedList не может дать вам преимущество в производительности.

2
ответ дан 13 апреля 2011 в 07:04 Источник Поделиться