【问题标题】:Optimize update request in loop循环优化更新请求
【发布时间】:2013-09-02 03:49:24
【问题描述】:

我有一个简单的用例,但它确实没有优化,我想知道它是否可以。

假设我有一个简单的实体,其中包含一个ID 和一个名为price 的变量(该实体称为Product)。

我正在使用HibernateJPA,我想每小时更新我的​​产品价格,所以这里是伪代码:

List<Product> products = Product.retrieveAll();
for (Product p : products) {
    p.price = makeSomeComplexComputationsToGetNextPrice();
    p.save();   // Updates the entity in the DB
}

这段代码非常简单。 makeSomeComplexComputationsToGetNextPrice(); 使用 CPU 进行一些计算,而且速度很快。

当我有 100 个产品时,一切正常(代码发出 101 个 sql 请求),但假设我有 10 000 个产品,代码发出 10 001 个 sql 请求,这需要几秒钟。

这个用例是我真实用例的简化版本,但问题就在这里:当我有太多产品时,执行需要很长时间(因为查询量很大)。

使用hibernateJPA,有没有办法优化这样的用例? (这段代码应该不到一秒的时间来执行,而且由于所有的查询,它需要的时间远远超过 1 秒)

非常感谢您的帮助

【问题讨论】:

  • makeSomeComplexComputationsToGetNextPrice 是用来访问数据库的?
  • 您为什么不尝试首先从数据库中检索您的数据,然后查询/操作/计算该数据?
  • @Christian 这就是 OP 目前正在做的事情。
  • @Christian 这就是我正在做的事情:检索产品,修改变量,然后通过 sql 更新它们

标签: java mysql sql hibernate jpa


【解决方案1】:

最简单的优化方法是使用批量传输。尝试计算大小为 N 的块,然后同时存储全部 N 个产品。而不是为每个存储(打开连接、存储、刷新、关闭连接)而努力,您只需为每个批量操作一次

更容易的是,当您选择整个产品数量作为批量大小时,可以有效地使其成为加载-计算-存储算法。

否则选择完美的批量大小可能会很棘手,因为它取决于很多参数,例如对象大小、您的数据库及其参数硬件等,但通常可以通过尝试不同的值和测量时间。

其他方法可能包括并行性(看起来不合适,因为您的 IO 是瓶颈)或调整您的数据库。

【讨论】:

  • 谢谢,但是如何使用Hibernate和JPA同时存储整个B产品?
  • 你必须看看你的表设计,阅读一些手册或谷歌你的数据库 + 批量传输。对不起,我不是 Hibernate 或 JPA 专家。通常,如果您将 store 方法用于一个打开的连接和一个关闭的连接,通常会带来很多性能。
【解决方案2】:

正如@EricStein 和@LastFreeNickname 指出的那样,使用批量插入,如果我们在p.save(); 讨论INSERT 命令,这是一个解决方案
但是如果makeSomeComplexComputationsToGetNextPrice(); 正在做一个DB 调用一些 SELECT 请求,然后首先查询那些复杂计算所需的所有数据,然后对其进行操作(再次使用 INSERTS 的批处理技术)。

【讨论】:

    【解决方案3】:

    如何使用批处理?我认为这通常是这样做的。

    http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/batch.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 2017-07-20
      相关资源
      最近更新 更多