Для Google App Engine (java), как установить и использовать размер блока в FetchOptions?
Im запускает запрос и в настоящее время возвращает 1400 результатов, и из-за этого я получаю следующее предупреждение в файле журнала:
com.google.appengine.api.datastore.QueryResultsSourceImpl logChunkSizeWarning: этот запрос не имеет размера блока, установленного в FetchOptions и вернул более 1000 результатов. Если наборы результатов этот размер является общим для этого запроса, рассмотрите настройку размера блока для улучшить производительность.
Я не могу найти нигде примеров того, как реально реализовать это, здесь есть вопрос о python, но поскольку я использую java и не понимаю python, я изо всех сил пытаюсь его перевести.
Также этот запрос (ниже) принимает 17226cpu_ms для выполнения, что слишком долго, я даже не могу представить, что произойдет, если бы я сказал 5000 контактов и должен был искать их на стороне клиента (например, вы делаете с контакты googlemail!)
Код, который у меня есть:
int index=0;
int numcontacts=0;
String[][] DetailList;
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
Query query = pm.newQuery(Contact.class, "AdminID == AID");
query.declareParameters("Long AID");
query.setOrdering("Name asc");
List<Contact> Contacts = (List<Contact>) query.execute(AdminID);
numcontacts=Contacts.size();
DetailList=new String[numcontacts][5];
for (Contact contact : Contacts)
{
DetailList[index][0]=contact.getID().toString();
DetailList[index][1]=Encode.EncodeString(contact.getName());
index++;
}
} finally {
pm.close();
}
return (DetailList);
Здесь я нашел следующие две записи:
но ни одна из них не содержит подробных сведений о том, как реализовать или использовать эти параметры.
Я предполагаю, что это процесс на стороне сервера, и я предполагаю, что вы собираетесь настроить какой-то цикл, чтобы захватить куски на один кусок за раз, но как я на самом деле это делаю?
- Я вызываю запрос внутри цикла?
- Как узнать, сколько раз цикл?
- Я просто проверяю первый кусок, который возвращается с меньшим количеством записей в количестве блоков?
Как я собирался разобраться с такими вещами без фактического примера?
Мне кажется, что другие люди здесь, похоже, "просто знают", как это сделать..!
Извините Если я не задаю вопросы правильно, или я просто тусклый новичок по этому поводу, но я не знаю, куда еще обратиться, чтобы понять это!
Ответы
Ответ 1
Встречая ту же проблему, и последний комментарий был сделан месяц назад, поэтому вот что я узнал о тяжелом запросе набора данных.
Я предполагаю, что после использования этих строк в документах google article (тот, что в питон, упомянутый кстати):
Эта статья была написана для версии SDK версии 1.1.7. Начиная с версии 1.3.1, курсоры запросов (Java | Python) имеют вытеснили описанные методы ниже и теперь является рекомендуемым методом подкачки через большие наборы данных.
В документах google о "Курсор курсора ".
Первая строка документа дает именно то, зачем нужна курсор:
Курсоры запросов позволяют приложению выполнять запрос и получать пакет результатов, затем получить дополнительные результаты для одного и того же запроса в последующий веб-запрос без накладных расходов смещения запроса.
В документации также представлен пример java сервлета с использованием техники курсора. Есть подсказка, как создать безопасный курсор для клиента. Наконец, раскрываются ограничения курсора.
Надеюсь, это поможет вам решить вашу проблему.
Небольшое напоминание о диапазоне и смещение, что сильно влияет на производительность, если забыто (и я сделал ^^):
Начальное смещение имеет последствия для производительности: хранилище данных должен извлекать и затем отбрасывать все результаты до начала смещение. Например, запрос с диапазоном 5, 10 выводит десять результатов из хранилища данных, затем отбрасывает первые пять и возвращает оставшиеся пять приложений.
Изменить: работая с JDO, я продолжал искать способ, чтобы мой предыдущий код загружал более 1000 результатов в один запрос. Итак, если вы используете JDO, я нашел этот старый issue:
Query query = pm.newQuery(...);
// I would use of value below 1000 (gae limit)
query.getFetchPlan().setFetchSize(numberOfRecordByFetch);
Ответ 2
Вот как я применяю FetchOptions
, по сравнению с вашим примером кода, вам может потребоваться немного настроить:
// ..... build the Query object
FetchOptions fetch_options =
FetchOptions.Builder.withPrefetchSize(100).chunkSize(100);
QueryResultList<Entity> returned_entities =
datastore_service_instance.prepare(query).asQueryResultList(fetch_options);
Конечно, цифры могут быть изменены (100).
Если мой ответ не тот, который вы ищете, тогда вы можете перефразировать свой вопрос (отредактировать).
Кстати, я тот, кто написал первый связанный вопрос.
Ответ 3
Если вы используете dataStore напрямую, без JDO, вы можете сделать что-то вроде следующего, чтобы установить размер блока, когда вы выполняете итерацию через данные:
Query query = new Query("entityname");
PreparedQuery preparedQuery = dataStore.prepare(query);
// the 200 should be less than 1000
FetchOptions options = FetchOptions.Builder.withChunkSize(200);
for (Entity result : preparedQuery.asIterable(options)) {
...
}