【问题标题】:Improve insert performance massively大幅提高插入性能
【发布时间】:2012-11-13 05:58:18
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: spring-data-jpa bulkinsert


    【解决方案1】:

    spring-data JPA: manual commit transaction and restart new one

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 我假设 postgres wozld 也支持不同的引擎。我的错。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 2021-08-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多