2

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

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

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

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 请求,这需要几秒钟。

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

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

非常感谢你的帮助

4

3 回答 3

2

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

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

于 2013-08-29T15:54:32.920 回答
2

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

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

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

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

于 2013-08-29T15:56:15.743 回答
1

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

于 2013-08-29T16:06:18.427 回答