循环优化更新请求

时间:2013-08-29 15:50:45

标签: java mysql sql hibernate jpa

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

假设我有一个包含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秒)

非常感谢你的帮助

3 个答案:

答案 0 :(得分:2)

使用批次怎么样?我认为这通常就是这样做的。

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

答案 1 :(得分:2)

最简单的优化方法是使用批量转移。尝试计算大小为N的大部分,然后同时存储整个N个产品。而不是为每个存储(开放连接,存储,刷新,关闭连接)做出努力,你只需每次批量

当你选择整个产品作为bulksize时,更加容易,有效地使它成为一个load-computeeach-store算法。

否则选择完美的体积大小可能会很棘手,因为它取决于很多参数,例如对象大小,数据库及其参数硬件等等,但通常只需通过尝试不同的值来发现一个好的值测量时间。

其他方式可能包括并行性(因为您的IO是瓶颈似乎不合适)或调整数据库。

答案 2 :(得分:1)

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