【问题标题】:Spring + Hibernate loading large amount recordsSpring + Hibernate 加载大量记录
【发布时间】:2019-03-30 14:33:49
【问题描述】:

我正在尝试找到在 Spring/Hibernate 服务中从 MySQL 数据库加载大量数据的最佳/最佳方式。

我从第 3 方 API 中提取大约 10 万条记录(通常在 300-1000 之间的块中),然后我需要从数据库中提取每条记录的翻译,因为有 30 种语言,这意味着每条记录将有 30 行,所以 1000来自 API 的记录是来自数据库的 30,000 行。

来自 API 的记录以 POJO 的形式(超小尺寸)说我得到 1000 条记录,我将列表分成多个 100 条记录列表,然后收集每条记录的 id 并从数据库中为这条记录选择所有翻译。我只需要表中的两个值,然后将它们添加到我的 POJO 中,然后将 POJO 推送到下一个服务。

基本上是这样的:

interface i18nRepository extends CrudRepository<Translation, Long> {}

List<APIRecord> records = api.findRecords(...);
List<List<APIRecord>> partitioned = Lists.partition(records, 100); // Guava 

for(List<APIRecord> chunk : partitioned) {
  List<Long> ids = new ArrayList();

  for(APIRecord record : chunk) {
    ids.add(record.getId());
  }

  List<Translation> translations = i18Repository.findAllByRecordIdIn(ids);

  for(APIRecord record : chunk) {
    for(Translation translation : translations) {
      if (translation.getRedordId() == record.getId()) {
        record.addTranslation(translation);
      }
    }
  }
}

就 spring-boot/hibernate 属性而言,我只设置了默认属性。我想让它尽可能高效、快速和内存精简。我的一个想法是使用底层 API 而不是 Hibernate 来绕过对象映射。

【问题讨论】:

  • 您可以使用PagingAndSortingRepository 界面对结果进行分页
  • 可以缓存数据库中的数据。试试ehcache,您可以快速添加它进行测试。重要的是您希望结果的实时性。
  • 文档中有几条建议:docs.jboss.org/hibernate/orm/current/userguide/html_single/…。我要补充一点,您的嵌套循环算法是 O(n^2)。使用 Map 会将其变成 O(n) 算法。但无论如何:你的问题是什么?
  • 1.你应该使用join。 2. 选择PageRequest的记录分块加载数据。 3.如果你的结果那么大。您可以使用临时表来保存结果。
  • @S.Denis join?什么 ? PageRequest 似乎是个好主意。

标签: java mysql spring hibernate spring-data-jpa


【解决方案1】:

在我看来,您应该绕过 JPA/Hibernate 进行批量操作。 在 JPA 中无法使批量操作高效。 考虑使用 Spring 的 JpaTemplate 和原生 SQL。

【讨论】:

    猜你喜欢
    • 2017-11-29
    • 1970-01-01
    • 2014-05-28
    • 2014-09-22
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多