【发布时间】:2018-12-30 09:24:32
【问题描述】:
我有一个使用游标(Objectify v5)的数据存储查询,我想在结果列表中的每个项目之后获取游标。代码如下所示:
public List<Puzzle> queryWithCursor(String cursor, String order, int limit) {
Query<Puzzle> query = ObjectifyService.ofy()
.load()
.type(Puzzle.class)
.order(order)
.limit(limit);
query = query.startAt(Cursor.fromWebSafeString(cursor));
List<Puzzle> puzzles = new ArrayList<>();
QueryResultIterator<Puzzle> iterator = query.iterator();
while (iterator.hasNext()) {
Puzzle puzzle = iterator.next();
puzzle.setCursor(iterator.getCursor().toWebSafeString());
puzzles.add(puzzle);
}
return puzzles;
}
虽然该方法正常工作,但它会在后台触发大量 Datastore 查询。基本上,每次 iterator.getCursor() 运行时,它都会触发一个额外的查询。我从 Stackdriver Trace 了解到,如果 limit 为 20,则该方法总共会触发 19 个查询(似乎最后一个 .getCursor() 不会触发额外的查询)。所以这种方法比使用偏移量的类似查询更慢,成本更高。
这真的是一个错误吗?有没有办法避免性能下降?
【问题讨论】:
-
在每次迭代中获取光标似乎是一件不寻常的事情 - 这可能是一个不同的问题,询问您想要实现的目标,可以为您提供更多有用的答案
-
嗨,格雷格,感谢您的回复。我认为您提供更多上下文是正确的。我有 2 个屏幕:PuzzleList 和 PuzzleDetail。 PuzzleList 显示一个谜题列表,当单击一个谜题时,它会打开 PuzzleDetail。从 PuzzleDetail 中,有一个 Next 按钮可以直接转到下一个未解决的谜题。这就是为什么我需要为 PuzzleList 中的每个拼图提供光标,以便我可以实现 Go Next 功能。目前我在查询中使用偏移量而不是游标,但由于读取操作的数量非常多,成本太高。
-
我不是 100% 确定我理解了你的问题,但是,有什么理由让你相信它应该减少查询?根据this,它会从光标定义的位置恢复查询,因此这将是一个新的 API 调用,这就是它出现在 Stackdriver 上的原因。如果我误解了您的问题,请告诉我。
-
@Hieu 您可以将您使用的“订单”传递给详细信息页面,然后使用它来构造适当的查询:for 'next' - 'ORDER by $orderField WHERE $orderField > currentItem。 $orderField LIMIT 1'(和
-
嗨格雷格,这对我不起作用,因为我想返回下一个“未解决”的难题,即我必须继续往下看,直到找到当前用户尚未解决的难题.
标签: performance google-app-engine objectify datastore database-cursor