我正在运行一个查询,它当前正在返回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);
我在这里找到了以下两个条目:
但实际上并未涉及有关如何实施或使用这些选项的任何细节。 我猜它是一个服务器端进程,我猜你是想设置某种循环来一次抓取一个块,但我该怎么做呢?
如果没有一个实际的例子,我是怎么想找到这样的东西? 在我看来,这里的其他人似乎“只知道”该怎么做..!
抱歉,如果我没有以正确的方式提问,或者我只是一个愚蠢的新手,但是我不知道还有什么可以解决这个问题!
答案 0 :(得分:4)
遇到同样的问题,最后一条评论来自一个月前,所以这里是我发现的重型数据集查询。
我想在阅读google docs article中的那些行之后我会使用“查询光标”技术(顺便提到的python中的那一行):
本文是为SDK 1.1.7版编写的。截至1.3.1版, 查询游标(Java | Python)已取代所描述的技术 下面是现在推荐的大型分页方法 数据集。
在关于“Query Cursor”的Google文档中。 doc的第一行正是为什么需要 cursor :
查询游标允许应用程序执行查询并检索一批查询 结果,然后在a中获取同一查询的其他结果 后续网站请求,没有查询偏移的开销。
该文档还提供了使用游标技术的servlet的 java示例。有一个提示如何为客户端生成一个安全的游标。最后,公开了 cursor 的限制。
希望这能帮助您解决问题。
关于范围和偏移的小提醒,如果忘记(我做了^^),对性能影响相当大:
起始偏移对性能有影响:数据存储 必须在开始之前检索并丢弃所有结果 偏移。例如,范围为5,10的查询会获取10个结果 从数据存储区,然后丢弃前五个并返回 剩下五个申请。
编辑:在使用JDO时,我一直在寻找一种方法来允许我以前的代码在单个查询中加载超过1000个结果。所以,如果你也使用JDO,我发现这个旧的issue:
Query query = pm.newQuery(...);
// I would use of value below 1000 (gae limit)
query.getFetchPlan().setFetchSize(numberOfRecordByFetch);
答案 1 :(得分:3)
这是我应用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)。
如果我的答案不是你想要的,那么欢迎你重新提出你的问题(编辑)。
顺便说一下,我是编写第一个链接问题的人。
答案 2 :(得分:1)
如果您直接使用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)) {
...
}