10

在我的应用程序中,我需要大幅提高插入性能。示例:包含大约 21K 记录的文件需要 100 多分钟才能插入。它可能需要一些时间是有原因的,比如 20 分钟左右,但超过 100 分钟太长了。

数据被插入到 3 个表中(多对多)。Id 是从序列生成的,但我已经用谷歌搜索并设置了hibernate.id.new_generator_mappings = trueallocationSize + 序列增量为 1000。

数据量也没什么特别的,文件是 90 mb。

我已经用visual vm验证了大部分时间都花在了jdbc驱动程序(postgresql)和hibernate上。我认为这个问题与子表中的唯一约束有关。服务层在插入之前会进行手动检查 (=SELECT)。如果记录已经存在,它会重用它而不是等待约束异常。

因此,总结一下特定文件,每个表将有 1 个插入(可能会有所不同,但对于理想(最快)情况下的这个文件来说不是)。这意味着总共 60k 插入 + 20k 选择。仍然超过 100 分钟似乎很长(是的,硬件很重要,它是在具有 7200 rpm 驱动器的简单 PC 上,没有 ssd 或 raid)。然而,这是对以前的应用程序(纯 jdbc)的改进版本,在此硬件上的相同插入大约需要 15 分钟。考虑到在这两种情况下,“预处理”都花费了大约 4-5 分钟,因此增加幅度很大。

任何可以改进的提示?有批量加载功能吗?

4

2 回答 2

6

spring-data JPA:手动提交事务并重新启动新事务

在每次第 n 次调用 save() 方法之后添加entityManager.flush()和。entityManager.clear()如果您使用休眠添加hibernate.jdbc.batch_size=100,这似乎是一个合理的选择。

性能提升 > 10 倍,可能接近 100 倍。

于 2013-02-18T13:16:54.650 回答
-1

听起来像一个数据库问题。检查您的表是否使用 InnoDB 或 MyISAM,根据我的经验,后者在插入时非常慢,并且是新数据库的默认设置。尽可能删除外键

如果您的问题确实与单个唯一索引有关,InnoDB 可以解决问题。

于 2012-11-25T08:46:10.640 回答