尝试优化我们的GAE / J数据存储区中的一个大查询,并在实验期间发现了一些不期望的结果。
代码本身非常简单,我在下面复制了:
public static CursorEntityWrapper<Media> getMediasByUsernameCursored(String username, String cursorString, int batchSize, MediaFetchGroup... fetchGroups) {
PersistenceManager pm = PMF.get().getPersistenceManager();
List<Media> result = new ArrayList<>();
Transaction tx = pm.currentTransaction();
try {
DBUtils.applyFetchGroups(pm, fetchGroups);
tx.begin();
Query query = pm.newQuery(Media.class);
query.getFetchPlan().setFetchSize(batchSize);
if (StringUtils.isNotBlank(cursorString)) {
Cursor c = Cursor.fromWebSafeString(cursorString);
Map<String, Object> extensionMap = new HashMap<>();
extensionMap.put(JDOCursorHelper.CURSOR_EXTENSION, c);
query.setExtensions(extensionMap);
}
query.setFilter("mediaUserString == userParam");
query.declareParameters("java.lang.String userParam");
query.setRange(0, batchSize);
result = (List<Media>) query.execute(username);
Cursor cursor = JDOCursorHelper.getCursor(result);
cursorString = cursor.toWebSafeString();
tx.commit();
} finally {
DBUtils.closeTransaction(tx, log);
DBUtils.closePMAndDetachResult(pm, result);
}
return results;}
如您所见,我们有一个查询方法可以按用户名返回所有实体Media。该实体有一些子实体,您可以将它们作为可选参数传入。
当要求其中一个大型fetchgroup时,我们的查询性能非常差。对于60个实体结果,返回需要大约10-15秒,而当结果为200大小时,响应最多可能需要40秒。
其中一个有趣的实验是我们认为事务应该对性能产生重大影响,因此我们从该方法中取消事务,并再次部署应用程序。但似乎我们错误的是,当交易没有呈现时,该方法变得更慢。
所以我的问题是为什么没有交易的查询会比交易慢?