如何优化AppEngine Java/JDO数据存储区put()以减少写入次数

Ash*_*der 5 java google-app-engine jdo

我正在调整我们在App Engine上运行的应用程序,其中一个最大的成本是数据存储读写.我注意到写作中最大的罪犯之一就是我们坚持订单.

基本数据是Order有很多项 - 我们分别存储和关联它们如下:

@PersistenceCapable
public class Order implements Serializable {

     @Persistent(mappedBy="order")
     @Element(dependent = "true")
     private List<Item> orderItems;

     // other fields too obviously
}

@PersistenceCapable
public class Item implements Serializable {

     @Persistent(dependent = "true")
     @JsonIgnore
     private Order order;

     // more fields...

}
Run Code Online (Sandbox Code Playgroud)

appstats显示了一个带有单个项目的订单的两个数据存储库 - 但两者都使用了大量的写入.我想知道从有经验的人那里优化这个的最好方法.

AppStats数据:

real = 34ms api = 1695ms cost = 6400 billed_ops = [DATASTORE_WRITE:64]

real = 42ms api = 995ms cost = 3600 billed_ops = [DATASTORE_WRITE:36]

appstats请求信息

我所知道的一些领域可能会有所帮助:

  1. 更少的索引 - 在许多订单和项目属性上有隐含的索引,我可以告诉它不要索引,例如item.quantity不是我需要查询的东西.但这就是所有这些写作的内容吗?
  2. 取消关联项目和订单,以便我只有一个实体OrderItem,根本不需要关系(但需要额外的存储空间).
  3. 在明确指数方面,我在订单表上只有1,按订单日期,在订单项上只有一个,按SKU /日期和关系的隐含一个.
  4. 如果这些项目是一个集合而不是一个列表,是否会完全取消对子项_IDX的索引?

所以,我的问题是,上述任何项目是否预示着大赢,或者是否有其他我错过的选项最好能够关注最初?

加分点:某处是否有一个很好的'数据存储写入较少的'指南'文章?

Pet*_*ego 2

计费文档明确指出:

  • 新实体放置(每个实体,无论实体大小):2 次写入 + 每个索引属性值 2 次写入 + 每个复合索引值 1 次写入

  • 现有实体放置(每个实体):1 次写入 + 每个修改后的索引属性值 4 次写入 + 每个修改后的复合索引值 2 次写入

  • 同样相关的是:App Engine 在实体的每个属性上预定义了一个简单的索引。

关于问题:

  1. 是的,写操作的数量与索引属性的数量有关。使它们取消索引以节省写入操作
  2. 将两个实体组合在一起可以节省 1 次写入(如果是新实体,则节省 2 次)。
  3. 您不需要只为一个属性设置“显式”索引。这些是由 appengine 自动生成的。您只需要显式配置复合索引,涵盖更多属性。
  4. 不。集合或列表(= 带顺序的集合)只是 Java 表示形式,Datastore API 始终在内部使用列表(= 添加的项目保留其顺序)。

更新:

索引数量影响写入成本,但不影响速度。写入分两个阶段完成:保存实体数据的提交阶段和构建索引的应用阶段。该put操作在提交阶段后返回,并且不受索引数量的影响。

在您的情况下,您将一个接一个地调用两个看跌期权。正如您从 AppStats 图表中看到的那样,它们是连续发生的。您可能希望将它们作为异步操作并行执行(不确定 JDO 中是​​否可用)。